home *** CD-ROM | disk | FTP | other *** search
- NAME mszibm
- ; File MSZIBM.ASM
- include mssdef.h
- ; Copyright (C) 1982,1993, Trustees of Columbia University in the
- ; City of New York. Permission is granted to any individual or
- ; institution to use, copy, or redistribute this software as long as
- ; it is not sold for profit and this copyright notice is retained.
- ;
- ; Terminal emulator module for IBM PC's and compatibles. Emulates Heath-19,
- ; VT52, VT102, and VT320, Honeywell VIP7809, Prime PT200, DG D463, and D470.
- ; Original version for VT100 done by James Harvey, Indiana Purdue Univ, for
- ; MS Kermit 2.27. Taken from there by Joe Doupnik, Utah State Univ for
- ; MS Kermit 2.29 et seq.
- ; Edit history
- ; 8 July 1993 version 3.13
- ; 6 Sept 1991 version 3.11
- ; Last edit 7 July 1993
- ; 6 Feb 1993 Add DG 470 color terminal.
- ; 6 Jan 1993. Add CSI ? 35 h/l as DEC macro to shift keyboard maps. In Kermit
- ; these invoke new macro names KEYBOARDS and KEYBOARDR, respectively. From
- ; Shalom Mitz, shmitz@coma.huji.ac.il.
- ; April 1992 Add Data General D463 terminal emulation.
- ; 7 Sept 1992 Add small extra code from htb to more fully emulate Prime PT200
- ; 20 July 1990 Include terminal type of VT100 as the same as VT102 but with
- ; a different ident response. Also include terminal type of HONEYWELL VIP7809
- ; as a VT100 with a VT100 ident response, with a canned response to ENQ, and
- ; another to ESC y. Honeywell material is from Frank Dreano,
- ; dreano@trout.nosc.mil.
- ; 29 May 1989 Rewrite and expand to DEC VT320 level.
- ; 5 Oct 1988 Add controls to write from right to left, using bit vswdir in
- ; the setup bytes vtemu.vtflgst and vtemu.vtflgop. The concept was invented
- ; by Baruch Cochavy, IIT, Haifa, Israel; the current code is by [jrd].
- ; If vswdir is non-zero writing is done starting on the visual right side.
- ; Procedure direction accomdates most directional details. The
- ; implementation here retains DX and CURSOR as logical values while the
- ; physical screen coordinates are conditioned via proc direction and
- ; several sections of special code. Screen printing is done full width if
- ; writing right to left. Outside mszibm the logical cursor = physical.
- ; 1 Jan 1988 version 2.30
- ; [Joe R. Doupnik, Utah State Univ]
-
- public anstty, ansini, ansrei, ansdsl, anskbi ; Entry points
- public ans52t, vsinit, tabset, tabclr, tekflg
- public mar_top, mar_bot, anspflg, scroll, cursor, curattr
- public dnparam, dparam, dlparam, dninter, dinter, emubufc, emubuf
- public emubufl, dcsstrf, upss, MNlatin
- public GRptr, G0set, G1set, G2set, G3set
- public savezlen, savezoff, blinkdis, protectena, dghscrdis
- public linescroll, xltkey, dgkbl, dgwindcomp, atctype, dgcross
- public dgnctoggle, apcstring
- ;
- ; DEC and VT are trademarks of Digital Equipment Corporation.
- ;
- ; Description of the global entry points and calls on external routines
- ; needed by this emulator.
- ;
- ; vsinit - start up routine called as Kermit initializes. Takes no arguments.
- ; Sets up address pointers to tabs, reads default terminal parameters
- ; reads current screen coloring. Examines and updates structure
- ; "vtemu." which is how mssset communicates changed information
- ; about many Set Term parameters; "flags." is a Kermit structure
- ; carrying the other Set Term parameters.
- ; anstty - starting point for displaying a character, delivered in AL.
- ; Returns when the display operation is completed and that may
- ; take many many instructions. All normal "characters received by
- ; the terminal" are provided by calling anstty with the char in AL.
- ; ansini - entry point to initialize the emulator. It requires information
- ; from msy in four registers: the Kermit terminal routine flags
- ; "yflags" (used mainly to sense debug mode and the mode line toggle)
- ; "low_rgt" (bh = row, bl = column of the lower right display corner)
- ; "lbaudtab" (index into baud rate table, for status reporting)
- ; "lpartab" (index into parity table, for status reporting)
- ; Ansini causes a full reset of the emulator, including screen
- ; clearing and a beep. Ansini is also called by msy in response to
- ; sensing the Alt = key combination to fully reset the emulator.
- ; ansrei - entry point to reinitialize the emulator. Nearly the same as
- ; ansini except operating flags, tabs, etc are retained from the
- ; previous emulator session. Items which can be changed by Set Term
- ; are examined and updated. The msy flags "yflags" are needed.
- ; This is the warm-restart entry point used when connect mode
- ; is reentered gracefully. The screen is cleared only if the coloring
- ; has changed. The starting cursor location is whereever msy puts it.
- ; ansdsl - display "led" (status line) information. Invoked by msy when
- ; the mode line is constructed so the emulator can write the
- ; terminal type and the VT100 led status lights when Connect mode
- ; is started. Requires "yflags" from msy to sense whether the mode
- ; line is to be shown.
- ; anskbi - a routine called by msy to notify the emulator that a character
- ; is available from the keyboard. No character is read, just flag
- ; ttkbi is set. This is actually used only to beep when the cursor
- ; goes beyond column 72 and the margin bell flag is on.
- ; ans52t - called by msy to change terminal types "on the fly" without
- ; fully updating all operating parameters and without losing setup
- ; information. Msy senses the Alt minus key and calls ans52t with
- ; no arguments. Ans52t cycles among terminal types.
- ; other modules in msy are called by this file to handle screen scrolling
- ; mode line on/off, output to the serial port (reports), screen
- ; particulars (location, cursor shape, blanking). The list is
- ; the set of code extrn procedures below; all are in file msy.
- ;
- ; data exchange is directly with msy to assist in scrolling (varaibles
- ; "mar_top", "mar_bot") and in sensing the non-connect
- ; mode screen coloring ("scbattr"). Screen coloring controlled by
- ; the emulator is not permitted to influence the non-connect mode
- ; screens whereas the emulator attempts to use the regular Kermit
- ; screen colors as defaults. The kind of terminal to emulate is
- ; held in word "flags.vtflg" which is set by Set Term and by this
- ; module for global information within Kermit.
- ;
- ; Many things have been added or modified since James Harvey donated this
- ; code to Columbia University for use in Kermit. [jrd]
- ; Character sets in VT320 and VT102 modes:
- ; ASCII ("B"/94)
- ; ISO Latin-1 ("A"/96)
- ; DEC UK-ASCII ("A"/94, available only in VT102 mode)
- ; DEC Supplemental Graphics ("%5"/94),
- ; DEC Technical Graphics (">"/94), an extension taken from the VT340,
- ; DEC Special Graphics ("0"/94 and "2"/94)
- ; ALT-ROM (Kermit specific, "1"/94/96)
- ; DEC National Replacement Chars (all 12 sets)
- ; Startup:
- ; GL = G0 = G1 = ASCII (or ALT-ROM if selected by SET TERM CHAR ALT-ROM),
- ; GR = G2 = G3 = ISO Latin-1.
- ; When an NRC is selected by SET TERM CHAR <country> and enabled by
- ; CSI ? 42 h the NRC table replaces G0..G3 at the time of selection. When
- ; thus designated and selected incoming characters are forced to 7 bits and
- ; 8-bit Controls (outgoing) is turned off. No designation means no selection.
- ; Selecting a character set with the wrong sized designator yields no action.
- ;
- ; Startup in D463/D470 mode:
- ; GL = G0 = ASCII
- ; GR = G1 = Data General International if using 8-bit characters, else
- ; GR = G1 = Data General Word Processing.
- ;
- ; References:
- ; "PT200 Programmers Reference Guide", 1984, Prime Computer # DOC 8621-001P
- ; "Video Terminal Model H19, Operation", 1979, Heath Company # 595-2284-05
- ; "VT100 User's Guide", 2nd ed., Jan 1979, DEC # EK-VT100-UG
- ; "Rainbow 100+/100B Terminal Emulation Manual", June 1984, DEC # QV069-GZ
- ; "Installing and Using The VT320 Video Terminal", June 1987,
- ; DEC # EK-VT320-UU-001
- ; "VT320 Programmer Reference Manual", July 1987, DEC # EK-VT320-RM-001
- ; "VT330/340 Programmer Ref Manual", 2nd ed, May 1988,
- ; Vol 1: Text programming DEC # EK-VT3XX-TP-002
- ; Vol 2: Graphics programming DEC # EK-VT3XX-GP-002
- ; "Programming the Display Terminal: Models D217, D413, and D463", Data
- ; General Corp, 014-00211-00, 1991.
- ; "Installing and Operating Your D216E+, D217, D413, and D463 Display
- ; Terminals", Data General Corp, 014-002057-01, 1991.
- ; "Dasher D470C Color Display Terminal, Programmer's Reference Manual",
- ; Data General Corp, 014-001015, 1984.
- ; ---------------------------------------------------------------------------
-
- vswidth equ 207 ; cross correlate with msyibm
- swidth equ 207 ; assumed max screen width
- slen equ 60 ; assumed max screen length
- maxparam equ 10 ; number of ESC and DCS Parameters
- maxinter equ 10 ; number of ESC and DCS Intermediates
- gsize equ 128 ; character set storage size
- ; anspflg bit field definitions:
- ; prtscr equ 1 ; used in msyibm print screen toggle
- vtautop equ 1 ; autoprint enabled (1)
- vtcntp equ 2 ; controller print enabled (1)
- vtextp equ 4 ; printer extent set (1)
- vtffp equ 10h ; form feed wanted at end of print (1)
-
- h19l25 equ 1 ; h19stat, line 25 enabled
- h19alf equ 2 ; h19stat, auto cr/lf when cr seen
- ; display save-info for dspstate
- dsptype equ 1 ; main (0) or status line (1) flag
- dspdecom equ 2 ; remembered origin mode (1=on)
-
- att_bold equ 08h ; bold in main video word
- att_blink equ 80h ; blinking in main video word
- att_protect equ 01h ; protected in vsatt
- att_uline equ 02h ; underscored in vsatt
- att_rev equ 04h ; reversed video in vsatt
-
- braceop equ 7bh ; opening curly brace
- bracecl equ 7dh ; closing curly brace
-
- ; DEC emulator status flags (bits in words vtemu.vtflgst and vtemu.vtflgop)
- ;anslnm equ 1H ; ANSI line feed/new line mode
- ;decawm equ 2H ; DEC autowrap mode
- ;decscnm equ 80H ; DEC screen mode
- ;decckm equ 200H ; DEC cursor keys mode
- ;deckpam equ 400H ; DEC keypad application mode
- ;decom equ 800H ; DEC origin mode
- ;deccol equ 1000H ; DEC column mode (0=80 col)
- ;decanm equ 2000H ; ANSI mode
- ;;dececho equ 4000H ; ANSI local echo on (1 = on)
-
- ; Terminal SETUP mode flags (joint with bits above, some name dups)
- ;vsnewline equ 1H ; ANSI new line (0 = off)
- ;vswrap equ 2H ; Line wrap around (0 = no wrap)
- ;vsnrcm equ 4H ; National Rep Char set (0=none)
- ;vswdir equ 8H ; Writing direction (0=left, 1 right)
- ;vskeyclick equ 10H ; Keyclick (0 = off)
- ;vsmarginbell equ 20H ; Margin bell (0 = off)
- ;vscursor equ 40H ; Cursor (0 = block, 1 = underline)
- ;vsscreen equ 80H ; Screen (0 = normal, 1 = rev. video)
- ;vscntl equ 100h ; 8 or 7 bit controls (1 = 8-bit)
- ;vshscroll equ 4000h ; horiz scroll (0=auto, 1=manual)
- ;vscompress equ 8000h ; compressed text(0=graphics,1=132col)
-
- ;vsdefaults equ 0+vscursor
-
- ; Kinds of terminals available
- ;ttgenrc equ 0 ; no emulation done by Kermit
- ;ttheath equ 1 ; Heath-19
- ;ttvt52 equ 2 ; VT52
- ;ttvt100 equ 4 ; VT100
- ;ttvt102 equ 8 ; VT102
- ;ttvt220 equ 10h ; VT220
- ;ttvt320 equ 20h ; VT320
- ;tttek equ 40h ; Tektronix 4010
- ;tthoney equ 80h ; Honeywell VIP7809
- ;ttpt200 equ 100h ; Prime PT200
- ;ttd463 equ 200h ; Data General D463
- ;ttd470 equ 400h ; Data General D440
- ;TTTYPES equ 12 ; Number of terminal types defined
- ;; tekflg bits in byte
- ;tek_active equ 1 ; actively in graphics mode
- ;tek_tek equ 2 ; Tek terminal
- ;tek_dec equ 4 ; Tek submode of DEC terminals
- ;tek_sg equ 8 ; special graphics mode
-
- ;emulst struc ; structure of vtemu.xxx for VTxxx emulator
- ;vtflgst dw 0 ; DEC setup flags (from SET)
- ;vtflgop dw 0 ; DEC runtime flags, like setup flags (here & STAT)
- ;vttbs dw 0 ; pointer to default tab stops, for SET
- ;vttbst dw 0 ; pointer to active tab stops, for STATUS
- ;vtchset db 1 ; value of default character set (1=US-ascii)
- ;att_ptr dw 0 ; pointer to normal & reverse video attributes
- ;emulst ends
- ;;;;;;;;;;;;;;;; end references ;;;;;;;;;;;;;;;;;;;;
-
- data segment
- extrn vtemu:byte, scbattr:byte, flags:byte, yflags:byte
- extrn crt_lins:byte, rxtable:byte, denyflg:word, low_rgt:word
- extrn vtclear:byte, dosnum:word, chcontrol:byte, apcenable:byte
- extrn parstate:word, pardone:word, parfail:word, nparam:word
- extrn param:word, lparam:byte, ninter:word, inter:byte, ttyact:byte
- extrn L1cp437:byte, L1cp850:byte, L1cp860:byte, L1cp863:byte
- extrn L1cp865:byte, modbuf:byte, extattr:byte, rdbuf:byte
- extrn vtenqenable:byte, vtcpage:word
-
- even ; C0 7-bit control code table
- ansc0 dw 5 dup (atign) ; NUL, SOH, STX, ETX, EOT
- dw atenq,atign,vtbell,atbs,atht ; ENQ, ACK, BEL, BS, HT
- dw atlf, atlf, atff, atcr,atls1 ; LF, VT, FF, CR, SO
- dw atls0, 4 dup (atign) ; SI, DLE, DC1, DC2, DC3
- dw 4 dup (atign), atcan ; DC4, NAK, SYN, ETB, CAN
- dw atign, atnrm, atesc,atign,atign ; EM, SUB, ESC, FS, GS
- dw 2 dup (atign) ; RS, US
-
- ; C1 8-bit control code table
- ansc1 dw 4 dup (atign), atind ; ignore 4, IND
- dw atnel,atign,atign,athts,atign ; NEL, SSA, ESA, HTS, HTJ
- dw atign,atign,atign,atri, atign ; VTS, PLD, PLU, RI, SS2
- dw atign,atdcs,3 dup (atign) ; SS3, DCS, PU1, PU2, STS
- dw atign,atign,protena,protdis,atign ; CCH, MW, SPA, EPA,ignore
- dw atign,atign,atcsi,atgotst,atdcsnul; ignore 2, CSI, ST, OSC
- dw atdcsnul, atapc ; PM, APC
-
- ; Heath-19 mode escape follower table
- h19esc db 36 ; number of entries
- dw h19ejt ; address of action routines
- db '<=>@A','BCDEF','GHIJK','LMNOY','Z[bjk','lnopq','rvwxy','z'
-
- ; Dispatch table for Heath-19 escape sequence table h19esc
- even
- h19ejt dw h19sans, atkpam, atkpnm, entins, atcuu ; '<=>@A'
- dw atcud, atcuf, atcub, h19clrs, v52sgm ; 'BCDEF'
- dw chrdef, atcup, atri0, ated, atel ; 'GHIJK'
- dw inslin, dellin, atdelc, noins, v52pos ; 'LMNOY'
- dw decid, h19csi, h19esos, h19sc, h19rc ; 'Z[bjk'
- dw h19erl, hrcup, h19ero, h19herv, h19hxrv ; 'lnopq'
- dw atnorm, h19wrap, h19nowrp,h19smod, h19cmod ; 'rvwxy'
- dw atxreset ; 'z'
-
- h19ans db 21 ; Heath-19 ANSI style escape sequences
- dw h19jmp ; address of action routine table
- db 'ABCDH','JKLMP','fhlmn','pqrsu','z'
-
- ; Heath-19 action table for h19ans
- even
- h19jmp dw atcuu, atcud, atcuf, atcub, atcup ; 'ABCDH'
- dw h19ed, atel, inslin, dellin, atdelc ; 'JKLMP'
- dw atcup, atsm, atrm, atsgr, rpcup ; 'fhlmn'
- dw atign, atign, atign, h19sc, h19rc ; 'pqrsu'
- dw atxreset ; 'z'
-
- ; VT52 compatibility mode escape follower table
- v52esc db 23 ; number of entries
- dw v52ejt ; address of action routines
- db '78<=>', 'ABCDF', 'GHIJK', 'VWXYZ'
- db ']',5eh,5fh ; 5eh = caret, 5fh = underscore
-
- ; Dispatch for v52esc table
- even
- v52ejt dw atsc, atrc, v52ans, atkpam, atkpnm ; '78<=>'
- dw atcuu, atcud, atcuf, atcub, v52sgm ; 'ABCDF'
- dw chrdef, atcup, atri0, ated, atel ; 'GHIJK'
- dw v52pl, v52pcb, v52pce, v52pos, decid ; 'VWXYZ'
- dw v52ps, v52pcb, v52pce ; ']^_'
-
- ; Prime PT200 escape follower table
- pt200esc db 38 ; number of entries
- dw p20ejt ; address of action routines
- db '01234','5678<', '=>?AB', 'DEFGH', 'JMNOP'
- db 'Z[\]',5eh ; 5eh = caret
- db 5fh,'cno',7bh ; 5fh=underscore, 7bh=left curly brace
- db 7ch,7dh,7eh ; 7ch=vert bar, 7dh=right curly brace, 7eh=tilde
-
- ; Dispatch for p20esc
- even
- p20ejt dw atdgf0, atdgf1, atdgf0, atsdhl, atsdhl ; '01234'
- dw 4 dup (atsdhl), atdgfu ; '5678<'
- dw atkpam, atnorm, p20ed, atdgfA, atdgfB ; '=>?AB'
- dw atind, atnel, ats7c, ats8c, athts ; 'DEFGH'
- dw ated, atri, atss2, atss3, atdcs ; 'JMNOP'
- dw decid, atcsi, atgotst, 2 dup(atdcsnul) ; 'Z[\]^'
- dw atdcsnul, atxreset,atls2, atls3, atpriv ; '_cno{'
- dw atls3r, atls2r, atls1r ; '|}~'
-
- ; VT320/VT102/VT100/Honewell ANSI mode escape follower table
- ansesc db 49 ; number of entries
- dw ansejt ; address of action routines
- db '01234','56789','<=>?A','BCDEF','GHKLMN','OPQRV'
- db 'WYZ[\',']',5eh,5fh ; 5eh = caret, 5fh=underscore
- db 60h,'c','fgno',7bh ; 7bh=left curly brace, 7ch=vert bar
- db 7ch,7dh,7eh ; 7dh=right curly brace, 7eh=tilde
-
- ; Dispatch for ansesc table
- even
- ansejt dw atdgf0, atdgf1, atdgf0, atsdhl, atsdhl ; '01234'
- dw 4 dup (atsdhl), atdgnrc ; '56789'
- dw atdgfu,atkpam, atdgft, atdgfq, atdgfA ; '<=>?A'
- dw atdgfB,atdgnrc, atind0, atnel0,ats7c ; 'BCDEF'
- dw ats8c, athts0, atdgnrc, atdgnrc,atri0, atss2 ; 'GHKLMN'
- dw atss3, atdcs0, atdgnrc, atdgnrc,protena ; 'OPQRV'
- dw protdis,decid, atdgnrc, atcsi0, atgotst0 ; 'WYZ[\'
- dw 2 dup (atdcsnul0),atapc, athoncls, atxreset ; ']^_`c'
- dw atdgnrc,atdgnrc,atls2,atls3, atpriv ; 'fgno{'
- dw atls3r, atls2r, atls1r ; '|}~'
-
- ; Final char table for VT320/VT102/VT100/Honeywell ANSI control sequences
- anstab db 38 ; number of entries
- dw ansjmp ; address of action routines
- db '@ABCD','EFGHI','JKLMP', 'Xacde','fghil','mnpqr','uwxyz'
- db 7ch,7dh,7eh ; 7dh=right curly brace, 7eh=tilde
-
- ; Dispatch for anstab table
- even
- ansjmp dw ansich, atcuu, atcud, atcuf, atcub ; '@ABCD'
- dw atcnl, atcpl, atcha, atcup, atcht ; 'EFGHI'
- dw ated, atel, inslin, dellin, atdelc ; 'JKLMP'
- dw atech, atcuf, atda, atcva, atcud ; 'Xacde'
- dw atcup, attbc, atsm, ansprt, atrm ; 'fghil'
- dw atsgr, atdsr, decscl, decsca, atstbm ; 'mnpqr'
- dw atrqtsr,atrqpsr,atreqt, atctst, atxreset ; 'uwxyz'
- dw atscpp, atsasd, atssdt ; '|}~'
-
- ; Final character table for Device Control Strings (DCS, ESC P)
- dcstab db 5 ; number of entries
- dw dcsjmp ; address of action routines
- db 'pqu',7bh,7ch ; 7bh = left curly brace
-
- ; Dispatch for dcstab table
- even
- dcsjmp dw atcrqq, atcrq, atupss, atdcsnul, atudk ; 'pqu{|'
- ;;; DCS Ps $ p string ST page 209 restore color palette
-
- ; Data General D463/D470 terminal section
- dgescape equ 1eh ; DG escape char (RS)
-
- even ; DG C0 7-bit control code table
- dgc0 dw atign,dgprtfm,dgrevidoff,dgblkena,dgblkdis;NUL,SOH,STX,ETX,EOT
- dw dgrwa,atign,vtbell,dgwinhome,atign ; ENQ, ACK, BEL, BS, HT
- dw dglf, dgeol, dgewin, dgcr,dgblkon ; LF, VT, FF, CR, SO
- dw dgblkoff,dgwwa,dgprtwn,dgrollena,dgrolldis ;SI,DLE,DC1,DC2,DC3
- dw dguson,dgusoff,dgrevidon,dgcuu,dgcuf ; DC4, NAK, SYN, ETB, CAN
- dw dgcub, dgcud,dgansi,dgdimon,dgdimoff ; EM, SUB, ESC, FS, GS
- dw dgesc, atign ; RS, US
-
- ; DG D463/D470 DG-escape (RS) follower table
- dgesctab db 17 ; number of entries
- dw dgejt ; address of action routines
- db 'ABCDE','FGHIJ','KLMNO','PR'
-
- ; Dispatch for dgesctab table
- even
- dgejt dw dgsfc, dgsbc, dgrmid, dgrevidon, dgrevidoff ; 'ABCDE'
- dw dgFSERIES, dgGSERIES, dgscrup, dgscrdn, inschr ; 'FGHIJ'
- dw dgdelc, dggline, atign, atls1, atls0 ; 'KLMNO'
- dw dgunix, dgRSERIES ; 'PR'
-
- fltable db 60 ; RS F letter dispatch table
- dw faction ; table of action routines
- db '789;<', '>?ABC', 'DEFGH', 'IJKLM', 'NOPQR'
- db 'STUVW', 'XYZ[\', ']^_`a', 'bcdef', 'hikmq'
- db 'rstvw', 'xz{}~'
-
- ; Dispatch for fltable table
- even
- faction dw dgign2n, atign, dggrid, atign, atign ; '789;<'
- dw dgalign, dgprt, atreset, dgsetw, dgsleft ; '>?ABC'
- dw dgsright, dgescn, dgeeos, dgshome, dginsl ; 'DEFGH'
- dw dgdell, dgnarrow, dgwide, dgpton, dgptoff ; 'IJKLM'
- dw dgchatr, dgrhso, dgwsa, dgsct, dgdefch ; 'NOPQR'
- dw dgscs, dgign1n, dg78bit, protena, protdis ; 'STUVW'
- dw dgsetmar, dgsetamar, dgrnmar, dgilbm, dgdlbm ; 'XYZ[\'
- dw dghsdis, dghsena, dgshcol, dgprt3a, atign ; ']^_`a'
- dw dgrsa, dgscmap, dgrchr, dgresch, dgskl ; 'bcdef'
- dw atign, atign, atnorm, atnorm, dgdcs ; 'hikmq'
- dw dgsclk, dgign1n, dgrss, dgrwc, dgrnmod ; 'rstvw'
- dw dgppb, dgs25l, dgsmid, dgnscur, dgign2n ; 'xz{}~'
-
- gltable db 14 ; RS G letter dispatch table
- dw gaction ; table of action routines
- db '018:>','?@ABC','HInp'
-
- ; Dispatch for gltable table
- even
- gaction dw dggarc, dggbar, dggline, dggpoly, dggcloc ; '018:>'
- dw dggrcl, dggcatt, dggcrst, dggcon, dggcoff ; '?@ABC'
- dw dggctrk, atnorm, atnorm, dggsetp ; 'HInp'
-
- rltable db 6 ; Data General D463/D470 RS R series
- dw raction
- db '@ABCD','E'
-
- ; Dispatch for rltable table
- raction dw dgign2n, dgsps, dgsfield, dgspage, dgsdo ; '@ABCD'
- dw dgdhdw ; 'E'
-
- ;; Notes on char set idents
- ; Kermit ident size ident comment designator
- ; 0 94 'B',0 ASCII "B"
- ; 1 94 'A',0 British NRC "A"
- ; 2 94 '4',0 Dutch NRC "4"
- ; 3 94 '5',0 Finnish NRC (also "C") "5"
- ; 4 94 'R',0 French NRC (also "f") "R"
- ; 5 94 '9',0 French Canadian NRC "9"
- ; 6 94 'K',0 German NRC "K"
- ; 7 94 'Y',0 Italian NRC "Y"
- ; 8 94 '`',0 Norwegian/Danish NRC "`"
- ; 9 94 '%','6' Portugese NRC ("L","g") "%6"
- ; 10 94 'Z',0 Spanish NRC "Z"
- ; 11 94 '7',0 Swedish NRC "7"
- ; 12 94 '=',0 Swiss NRC "="
- ; 13 94 '=','%' DEC Hebrew NRC "=%'
- ; 14 94 '1',0 Alt-ROM "1"
- ; 15 96 '?',0 Transparent "?"
- ; 16 96 'A',0 Latin1 "A"
- ; 17 94 '%','5' DEC Multinat (Sup Gr) "%5"
- ; 18 94 '>',0 DEC Technical ">"
- ; 19 94 '0',0 DEC-Special "0","2"
- ; 20 94 'D','I' DG International "DI"
- ; 21 94 'D','L' DG Line Drawing "DL"
- ; 22 94 'D','W' DG Word Processing "DW"
- ; 23 96 'B',0 Latin2 "B"
- ; 24 96 'H',0 Hebrew-ISO "H"
- ; 25 94 '"','4' DEC Hebrew ""4"
- ; 100 94 'D','U' DG soft set filler "DU"
- ;; End of notes
-
- ; Heath-19 special graphics characters to CP437. Use as offsets from caret
- ; (94D)
- hgrtab db 249, 17,179,196,197 ; caret,underscore,accent grave,a,b
- db 191,217,192,218,241 ; c,d,e,f,g
- db 26,177,219, 25,220 ; h,i,j,k,l
- db 220,223,223,223,222 ; m,n,o,p,q
- db 16,194,180,193,195 ; r,s,t,u,v
- db 'X','/','\',223,220 ; w,x,y,z,left curly brace
- db 221,222, 20 ; vertical bar,right curly brace,tilde
- hgrtabl equ ($-hgrtab)
-
- ; Data General Line Drawing Character Set, based on CP437, starting in 10/0
- dgldc db 20h,0dah,0bfh,0c0h,0d9h,0c2h,0b4h,0c3h ; 2/0
- db 0c1h,0c5h,0b3h,0c4h,0c2h,0b4h,0c3h,0c1h
- db 0b3h,0c9h,0bbh,0c8h,0bch,0cbh,0b9h,0cch ; 3/0
- db 0cah,0ceh,0bah,0cdh,0c4h,0f6h,9bh,3fh
- db 3fh,3fh,3fh ; 4/0
- dgldclen equ ($-dgldc)
-
- ; VT320/VT102 "Special graphics" set translation table for characters 95..126d
- ; when the special graphics set is selected. Some characters (98, 99, 100,
- ; 101, 104, 105, 111, 112, 114, 115, and 116) do not have exact equivalents
- ; in the available set on the IBM, so a close substitution is made.
- ; Table is indexed by ASCII char value minus 95 for chars 95..126d.
- sgrtab db 32, 4,177, 26, 23, 27, 25,248,241, 21
- db 18,217,191,218,192, 197,196,196,196,196
- db 196,195,180,193,194, 179,243,242,227,157
- db 156,250
- sgrtabl equ $-sgrtab
-
-
- ; DEC National Replacement Char sets, referenced to Latin1
- nrclat db 23h,40h,5bh,5ch,5dh,5eh ; 0, ASCII, "B", dispatch ref
- db 5fh,60h,7bh,7ch,7dh,7eh
- db 94,'B',0 ; 94 byte set, letter pair
- db 0a3h,40h,5bh,5ch,5dh,5eh ; 1, British, "A"
- db 5fh,60h,7bh,7ch,7dh,7eh
- db 94,'A',0
- db 0a3h,0beh,0ffh,0bdh,7ch,5eh ; 2, Dutch, "4"
- db 5fh,60h,0a8h,66h,0bch,0b4h
- db 94,'4',0
- db 23h,40h,0c4h,0d6h,0c5h,0dch ; 3, Finnish, "5"
- db 5fh,0e9h,0e4h,0f6h,0e5h,0fch
- db 94,'5',0
- db 0a3h,0e0h,0b0h,0e7h,0a7h,5eh ; 4, French, "R"
- db 5fh,60h,0e9h,0f9h,0e8h,0fbh
- db 94,'R',0
- db 23h,0e0h,0e2h,0e7h,0eah,0eeh ; 5, French Canadian, "9"
- db 5fh,0f4h,0e9h,0f9h,0e8h,0f8h
- db 94,'9',0
- db 23h,0a7h,0c4h,0d6h,0dch,5eh ; 6, German, "K"
- db 5fh,60h,0e4h,0f6h,0fch,0dfh
- db 94,'K',0
- db 0a3h,0a7h,0b0h,0e7h,0e9h,5eh ; 7, Italian, "Y"
- db 5fh,97h,0e0h,0f2h,0e8h,0ech
- db 94,'Y',0
- db 23h,40h,0c6h,0d8h,0c5h,5eh ; 8, Norwegian/Danish, "`"
- db 5fh,60h,0e6h,0f8h,0e5h,7eh
- db 94,60h,0
- db 23h,60h,0c3h,0c7h,0d5h,5eh ; 9, Portugese, "%6"
- db 5fh,60h,0e3h,0e7h,0f5h,7eh
- db 94,'%','6'
- db 0a3h,0a7h,0a1h,0d1h,0bfh,5eh ; 10, Spanish, "Z"
- db 5fh,60h,0b0h,0f1h,0e7h,7eh
- db 94,'Z',0
- db 23h,0c9h,0c4h,0d6h,0c5h,0dch ; 11, Swedish, "7"
- db 5fh,0e9h,0e4h,0f6h,0e5h,0fch
- db 94,'7',0
- db 0f9h,0e0h,0e9h,0e7h,0eah,0eeh ; 12, Swiss, "="
- db 0e8h,0f4h,0e4h,0f6h,0fch,0fbh
- db 94,'=',0
-
- nrcfinal db 'A45CRf9QKY`E6Z7H=Lg' ; NRC country letters
- nrcflen equ $-nrcfinal ; "%6" "%=" done separately
- nrcnum db 1,2,3,3,4,4,5,5,6,7,8,8,8,10,11,11,12,9,9
- ; country numbers matching
- ; nrcfinal letters
-
- ;NRC to DEC keyboard codes, North American (ASCII is nrckbd 1),+ALT-ROM+transp
- nrckbd db 1,2,8,6,14,4,7,9,13,16,15,12,11,1, 1,1,1,1,1,1,1
- ;NRC to DG keyboard codes, North American + ALT-ROM+transparent
- nrcdgkbd db 19h,1ah,0,1dh,1bh,18h,1ch,17h,1fh,0,1eh,1dh,14h,19h, 19h,18h
- db 19h,19h,19h,19h,19h
- ; DG char set idents to Kermit set idents
- ; DG set values 0 1 2 3 4 5 6 7 8 9 0a 0b 0c 0d 0e 0f hex
- dgchtab db 0,0,1,4,6,11,10,8, 12,100,100,100,100,100,20,100 ; decimal
- ; 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
- db 22,21,100,15,17,19,100, 100,100,100,100,100,100, 0,15,16
- ; 20h and above map to soft set filler 100
- db 100 ; filler set
-
- ; Translation tables for byte codes 0a0h..0ffh to map DEC Multinational
- ; Character Set (DEC Supplemental Graphic) to Code Pages.
- ; Codes 00h-1fh are 7-bit controls (C0), codes 20h..7eh are ASCII, 7fh DEL is
- ; considered to be a control code, 80h..9fh are 8-bit controls (C1).
- ; Each table is 128 translatable bytes followed by the table size (94) and the
- ; ISO announcer ident '%5'.
-
- MNlatin db 0a4h,0a6h,0a8h,0ach,0adh,0aeh,0afh,0b4h ; Latin1 code points
- db 0beh,0d0h,0d7h,0deh,0f0h,0fdh,0feh,0ffh
- db 20h,20h,0a4h,20h,20h,20h,20h,20h ; MN values there
- db 20h,20h,3fh,20h,20h,0ffh,20h,20h
-
-
- ; Dec Technical set to CP437, CP860, CP863, CP865
- ; Note: CP850 lacks the symbols so expect trash
- dectech db 32 dup (0) ; columns 8 and 9
- db 0h,0fbh,0dah,0c4h, 0f4h,0f5h,0b3h,0dah ; column 10
- db 0c0h,0bfh,0d9h,28h,28h,29h,29h,0b4h
- db 0c3h,3ch,3eh,5ch, 2fh,0bfh,0d9h,03eh ; column 11
- db 0a8h,20h,20h,20h, 0f3h,3dh,0f2h,3fh
- db 1eh,0ech,0ech,0f6h,1eh,1fh,0e8h,0e2h ; column 12
- db 0f7h,0f7h,0e9h,58h,3fh,1dh,1ah,0f0h
- db 0e3h,3fh,20h,0e4h, 20h,20h,0fbh,0eah ; column 13
- db 3fh,54h,3fh,3fh, 0efh,55h,5eh,76h
- db 0aah,0e0h,0e1h,78h,0ebh,0eeh,0edh,3fh ; column 14
- db 6eh,69h,0e9h,6bh, 3fh,20h,76h,3fh
- db 0e3h,3fh,70h,0e5h, 0e7h,0a8h,9fh,77h ; column 15
- db 45h,76h,3fh,1bh, 18h,1ah,19h,7fh
- db 94,3eh,0 ; 94 byte set, letter ident
-
- ; Data General Word Processing to CP 437
- dgwpcp437 db 20h,0dah,0c0h,0bfh, 0d9h,9fh,'~',8h ; column 10
- db 0e4h,0e4h,0f4h,0f5h, 0fbh,8h,0ech,8h
- db '0','1',0fdh,'3', '4','5','6','7' ; column 11
- db '8','9',8h,0c9h, 1bh,8h,1ah,0fah
- db 13h,0e0h,0e1h,8h, 0ebh,8h,8h,0fch ; column 12
- db 0e9h,8h,8h,8h, 0e6h,8h,0eeh,8h
- db 8h,8h,0e5h,0e7h, 8h,0edh,8h,8h ; column 13
- db 8h,0eah,1eh,14h, 4 dup (8h)
- db 0c3h,04h,010h,010h, 011h,1eh,1fh,9 dup (8h) ; column 14
- db '0','1','2','3', '4','5','6','7' ; column 15
- db '8','9',3fh,18h, 1ah,1bh,19h,20h
- db 94,'D','W' ; 94 byte set, letter idents
- dgwplen equ $-dgwpcp437 ; table size
-
- ; Convert Data General International to Latin1.
- ; DGI chars at these code points translate to the
- ; value used as a code point in the Latin1 table.
- ; Thus the second byte, 0ach, DGI not sign, in its
- ; row 2 col 10 translates to Latin1 not sign in row 12
- ; col 10. Columns 8 and 9 are C1 controls.
- dgi2lat db 0a0h,0ach,0bdh,0b5h, 0b2h,0b3h,0a4h,0a2h ; column 10
- db 0a3h,0aah,0bah,0a1h, 0bfh,0a9h,0aeh,3fh
- db 0bbh,0abh,0b6h,3fh, 3fh,0a5h,0b1h,3fh ; column 11
- db 3fh,0b7h,60h,0a7h, 0b0h,0a8h,0b4h,3fh
- db 0c1h,0c0h,0c2h,0c4h, 0c3h,0c5h,0c6h,0c7h ; column 12
- db 0c9h,0c8h,0cah,0cbh, 0cdh,0cch,0ceh,0cfh
- db 0d1h,0d3h,0d2h,0d4h, 0d6h,0d5h,0d8h,3fh ; column 13
- db 0dah,0d9h,0dbh,0dch, 0a0h,59h,0a0h,0a0h
- db 0e1h,0e0h,0e2h,0e4h, 0e3h,0e5h,0e6h,0e7h ; column 14
- db 0e9h,0e8h,0eah,0ebh, 0edh,0ech,0eeh,0efh
- db 0f1h,0f3h,0f2h,0f4h, 0f6h,0f5h,0f8h,3fh ; column 15
- db 0fah,0f9h,0fbh,0fch, 0dfh,0ffh,0a0h,0a0h
- dgi2len equ $-dgi2lat
- ; Device attributes response string. Make strings asciiz.
- v32str db escape,'[?63;1;2;4;6;8;9;15c',0 ; VT320, level 3, 132 col,
- ;printer, selective chars, Sixel graphics, UDkeys, NRC, DEC Tech Chars
- v32sda db escape,'[>24;0;0c',0 ; VT320 secondary DA response
- v22str db escape,'[?62;1;2;4;6;8;9;15c',0; VT220, level 2, etc as above
- v102str db escape,'[?6c',0 ; VT102
- v100str db escape,'[?1c',0 ; vanilla VT100
- v52str db escape,'/Z',0 ; VT100 in VT52 compatibility mode
- h19str db escape,'/K',0 ; Heath-19 (says plain VT52)
- VIPstr db escape,'[8p OT',03h,escape,'[y7813 P GC A ',03h,0
- VIPstrl equ $-VIPstr ; Honeywell MOD400 3.1 id for ESC [ y
- ENQhstr db '7813 P GC A',03h ; Honeywell MOD400 4.0 id string
- ENQhstrl equ $-ENQhstr
- pt20str db escape,'! ~0 ~..6~C~2 ~$',0 ; Prime PT200
- ENQstr db 'MS-DOS KERMIT' ; generic enquiry response
- ENQstrl equ $-ENQstr
- ; parity code translation table
- partab db 5,3,1,4,2 ; even, mark, none, odd, space
- lpartab equ $-partab
- parcode db 0 ; parity code (0-4)
- ; baud rate code translation table
- ; 45.5 - no VT100 code (call it 50),50,75,110,134.5,150,300,600,1200,
- ; 1800,2000,2400,4800,9600,19200,38400,57600,115200 extended beyond DEC
- baudtab db 0,0,8,16,24,32,48,56,64,72,80,88,104,112,120,128,128,128,64,8
- lbaudtab equ $-baudtab-1 ; last two are 1200/75 for split speeds
- baudidx db 0 ; index into baud rate table
- datbits db 7 ; number of databits (7 or 8)
-
- ;;;;;;;;;;;;;;; start session save area
- even
- savezoff label word
- ttstate dw offset atnrm ; terminal automata state
- ttstateST dw offset atnorm ; state for action after ST seen
- apcstring dw 0 ; segment of apcmacro memory
- bracecount db 0 ; count of curly braces in APC string
- att_normal db 07H ; default normal screen coloring
- oldterm dw 0 ; terminal type from previous entry
- tekflg db 0 ; Tek mode active flag
- old8bit db -1 ; flags.remflg setting for D463/D470
- iniflgs dw 0 ; status flags at entry time
- modeset db 0 ; temp for atsm/atrm
- anspflg db 0 ; printer flag bits and definitions
- h19stat db 0 ; H-19 extra status bits
- h19ctyp db 1 ; H-19 cursor type (1=ul, 2=bk, 4=off)
- h19cur dw 0 ; H-19 saved cursor position
- insmod db 0 ; insert mode on (1) or off (0)
- belcol db 72 ; column at which to ring margin bell
- kbicsr dw 0 ; cursor when keyboard input typed
- kbiflg db 0 ; set/reset for keyboard input
- ttkbi db 0 ; flag for keyboard input seen
- atescftab dw ansesc ; offset of esc follower table
- setptr dw 0 ; hold offset of designated char set
- upss db 96,'A',0,0 ; User Preferred Supplemental Set
- ; size, ident (DEC Supplemental Gr)
- ; tab stops, stored here
- tabs db (swidth+7)/8 dup (0) ; active tab stops, one column per bit
- deftabs db (swidth+7)/8 dup (0) ; default (setup) tab stops
- ; byte per line, type of line: 0=normal, 1=double wide, 2=double high
- linetype db slen dup (0) ; single/double width chars for a line
- linescroll db slen dup (0) ; horizontal scroll for each line
- oldscrn dw 0 ; old screen. hi=rows-1, low=cols-1
-
- ; Scrolling region - do not separate or change order of mar_top & mar_bot
- mar_top db 0 ; scrolling region top margin
- mar_bot db 23 ; scrolling region bottom margin
- mar_left db 0 ; left margin
- mar_right db vswidth-1 ; right margin
- savdgmar dw 0 ; DG saved right/left margins
- dspstate db 0 ; display state (mode)line work byte
- dspmsave dw 0 ; saved main dsp scrolling margins
- dspcstat dw 0 ; saved cursor pos for status line
- dspcmain dw 0 ; saved cursor pos for main display
- G0set db gsize+3 dup (0),0 ; G0..G3 char set space
- G1set db gsize+3 dup (0),1 ; last byte is permanent set index
- G2set db gsize+3 dup (0),2 ; and should never be changed
- G3set db gsize+3 dup (0),3
- ; Start of save cursor material
- savelist equ this byte ; top of list of things to save
- havesaved db 0 ; if have saved anything
- cursor dw 0 ; cursor position
- savextattr db 0 ; extended display attributes
- curattr db 07h ; cursor attribute
- svattr_index equ $-savelist ; offset of saved cursor attribute
- savscbattr db 1 ; normal background attributes
- atctype db 1 ; VTxxx cursor type (1=ul,2=bk,0/4=off)
- savflgs dw 0 ; saved flags for atsc/atrc
- atwrap db 0 ; autowrap flag
- decrlm db 0 ; host controlled right-left writing
- GLptr dw 0 ; pointer to char set for GL
- GRptr dw 0 ; pointer to char set for GR
- SSptr dw 0 ; pointer to char set for single shift
- Gsetid db 4 dup (0) ; set numbers 0..24 of char set
- lsavecu equ $-savelist ; length of stuff to save
- savecu db lsavecu dup (0) ; saved cursor, attr., charset, etc
- ; End of save cursor material
- even ; Control sequence storage area
- dnparam dw 0 ; number of parameters for DCS
- dparam dw maxparam dup (0) ; Parameters for DCS
- dlparam db 0 ; a single letter Parameter for DCS
- dninter dw 0 ; number of DCS intermediates
- dinter db maxinter dup (0) ; Intermediates for DCS
- dcsstrf db 0 ; Final char of DCS
- emubufc dw 0 ; count of chars in string buffer
- emubuf db 66 dup (0) ; emulator string storage buffer
- db 0 ; safety for string overflow
- emubufl dw $-emubuf ; length of emulator buffer
- ; DG windows structure
- dgwindcnt dw 1 ; DG count of active windows
- dgwindow dw 25 dup (0) ; DG window [mar_top,mar_bot]
- dgwindcomp db 25 dup (0) ; DG window compress (0=80,1=132 cols)
- dgcaller dw atnorm ; DG hex proc callback address
- numdigits db 0 ; DG hex digits remaining to be done
- dgnum dw 0 ; DG numerical result
- protectena db 0 ; DG protected mode enabled
- blinkdis db 0 ; DG blink disabled
- dgroll db 1 ; DG roll (0=disabled, 1=enabled)
- dghscrdis db 0 ; DG horz scroll disabled (if 1)
- dgcursave dw 16 dup (0) ; DG cursor position named save area
- dgctypesave db 16 dup (0) ; DG cursor type named save area
- dgcross db 0 ; DG crosshair activity: 0=off, 1=on
- ; 2 = track keypad, 4= track mouse
- dg463fore db 0 ; DG D463 Polygon fill foregnd color
- dgaltid dw 0 ; DG alt term id from host (0=none)
- dgkbl db 0 ; DG keyboard language
- dglinepat dw 0ffffh ; DG line drawing pattern
- thisline db 0 ; linetype for current line
- scroll db 1 ; lines to scroll, temp worker
- savezlen dw ($-savezoff) ; length of z save area
- ;;;;;;;;;;;;;;;;; end of session save area
-
- ;note low_rgt dw 0 ; text screen dimensions
- ; byte low_rgt = max column (79)
- ; byte low_rgt+1 = max row (23)
- led_col equ 65 ; column position for "LEDs" display
- led_off equ '.' ; "Off" LED
- v320leds db 'VT320 ....' ; VT320 mode (all 10 characters)
- v220leds db 'VT220 ....' ; VT220 mode
- v102leds db 'VT102 ....' ; VT102 mode
- v100leds db 'VT100 ....' ; VT100 mode
- v52leds db 'VT52 ' ; VT52 mode
- h19leds db 'Heath-19 ' ; Heath-19 mode
- honeyleds db 'Honey ....' ; Honeywell VIP 7809
- pt20leds db 'PT200 ....' ; Prime PT200
- d470leds db 'D470 ' ; D470 series from Data General
- d470model db 'D470' ; D470 response for Read New Model ID
- d463leds db 'D463 ' ; D463 series from Data General
- d463model db 'D463' ; D463 response for Read New Model ID
- ;;d413model db 'D413' ; D413 response for Read New Model ID
- data ends
-
- code2 segment
- extrn tekini:far, tekemu:far, tekend:far, teksetcursor:far
- extrn dgline:far, dgbar:far, dgcrosson:far, dgcrossoff:far
- extrn dgcrossrpt:far, dgsetcrloc:far, dgarc:far, dgpoly:far
- code2 ends
-
- code segment
- extrn cptchr:near, pntchr:near, pntchk:near, pntflsh:near
- extrn modlin:near, latin1:near
- extrn clrmod:near, dec2di:near, latininv:near, trnprs:near
- extrn dgsettek:far, vtksmac:near, vtkrmac:near, product:near
-
- assume ds:data, es:nothing
-
- fmodlin proc far
- call modlin
- ret
- fmodlin endp
-
- fclrmod proc far
- call clrmod
- ret
- fclrmod endp
-
- fcptchr proc far
- call cptchr
- ret
- fcptchr endp
-
- fdec2di proc far
- call dec2di
- ret
- fdec2di endp
-
- fpntchr proc far
- call pntchr
- ret
- fpntchr endp
-
- fpntchk proc far
- call pntchk
- ret
- fpntchk endp
-
- fpntflsh proc far
- call pntflsh
- ret
- fpntflsh endp
-
- ftrnprs proc far
- call trnprs
- ret
- ftrnprs endp
-
- fvtksmac proc far
- call vtksmac
- ret
- fvtksmac endp
-
- fvtkrmac proc far
- call vtkrmac
- ret
- fvtkrmac endp
-
- fproduct proc far
- call product
- ret
- fproduct endp
-
- flatin1 proc far
- push flags.chrset
- mov ax,vtcpage ; get current terminal Code Page
- mov flags.chrset,ax ; tell file transfer part
- call latin1
- call latininv
- pop flags.chrset
- ret
- flatin1 endp
- code ends
-
- code1 segment
- extrn prtbout:near, prtnout:near, csrtype:near, atsclr:near
- extrn vtscru:near, vtscrd:near, chgdsp:near
- extrn setpos:near, setudk:near, udkclear:near, vtbell:near
- extrn setatch:near, qsetatch:near, getatch:near
- extrn revideo:near, getbold:near, setbold:near, clrbold:near
- extrn getblink:near, setblink:near, clrblink:near, getunder:near
- extrn setunder:near, clrunder:near, revscn:near, setcolor:near
- extrn setrev:near, clrrev:near, tekrpal:near
- extrn tekinq:near, tekpal:near, tekrpal:near
- extrn atparse:near, atpclr:near, atdispat:near, apcmacro:near
- extrn setprot:near, clrprot:near, frepaint:far, touchup:near
-
- assume cs:code1, ds:data, es:nothing
-
- ; Terminal display routine. Call with character incoming character in AL
-
- anstty proc near
- mov dx,cursor ; some routines need cursor in dx
- mov kbiflg,0 ; clear old flag value
- test yflags,trnctl ; Debug mode?
- jz anstt1 ; z = no
- jmp atdeb ; yes, just translate control chars
- anstt1: cmp ttkbi,0 ; new keyboard input?
- je anstt2 ; e = no, just continue
- mov kbiflg,1 ; yes, set flag
- mov kbicsr,dx ; save old cursor
- mov ttkbi,0 ; clear this flag
-
- anstt2: test anspflg,vtcntp ; print controller on?
- jz anstt4 ; z = no
- test flags.capflg,logses ; capturing output?
- jz anstt3 ; z = no, forget this part
- push ax ; save char
- call fcptchr ; give it captured character
- pop ax ; restore character
- anstt3: jmp ttstate ; print transparently
-
- anstt4: test flags.vtflg,ttd463+ttd470 ; DG D463/D470 mode?
- jnz anstt4a ; nz = yes, must pass nulls
- or al,al ; NUL char?
- jz atign ; z = yes, ignore it before logging
- anstt4a:test yflags,capt ; capturing output?
- jz anstt8 ; z = no, forget this part
- call fcptchr ; give it captured character
- ; Direct char to processor module
- anstt8: test flags.vtflg,ttd463+ttd470 ; DG D463/D470 mode?
- jnz anstt10 ; nz = yes
- cmp vtemu.vtchset,13 ; ASCII (0) or NRC's (1-13) active?
- ja anstt8b ; a = no
- cmp vtemu.vtchset,0 ; ASCII?
- je anstt8b ; e = yes
- and al,7fh ; yes, NRCs force chars to 7-bits
- anstt8b:test al,not 9fh ; control chars (0-1fh, 80h-9fh)?
- jnz anstt9 ; nz = no
- cmp al,20h ; C0 control code?
- jb anstt8c ; b = yes
- cmp vtemu.vtchset,15 ; TRANSPARENT?
- je anstt9 ; e = yes, pass all others
- anstt8c:jmp atctrl ; dispatch on control code
- anstt9: jmp ttstate ; dispatch according to state
-
- ; DG D463/D470 terminal
- anstt10:test flags.remflg,d8bit ; use high bit?
- jnz anstt11 ; nz = yes
- and al,7fh ; 7 bit terminal only
- anstt11:test anspflg,vtcntp ; controller (transparent) printing?
- jnz anstt12 ; nz = yes, go through filter routine
- cmp al,20h ; C0 control code?
- jae anstt12 ; ae = no, do according to ttstate
- cmp ttstate,offset atnrm ; normal text processing?
- jne anstt12 ; ne = no, pass controls to state
- jmp dgctrl ; do DG controls
- anstt12:jmp ttstate ; process regularly
- anstty endp
-
- atign: ret ; something to be ignored
-
- atnorm: mov ttstate,offset atnrm ; reset state to "normal"
- mov ttstateST,offset atnorm ; reset state for ST seen
- ret
-
- atnrm proc near ; Normal character (in AL) processor
- cmp SSptr,0 ; single shift needed?
- je atnrm10 ; e = no
- and al,not 80h ; strip high bit
- mov bx,SSptr ; pointer to desired char set
- mov SSptr,0 ; clear single shift indicator
- jmp short atnrm12 ; process
-
- atnrm10:test al,80h ; high bit set for GRight?
- jnz atnrm11 ; nz = yes
- mov bx,GLptr ; GL char set
- jmp short atnrm12 ; process
-
- atnrm11:and al,not 80h ; strip high bit
- mov bx,GRptr ; GR char set
-
- atnrm12:xlatb ; translate al to new char in al
- atnrm13:cmp rxtable+256,0 ; TRANSLATION INPUT turned off?
- je atnrm14 ; e = yes, use ISO mechanisms
- mov bx,offset rxtable ; address of translate table
- mov ah,al ; copy char
- xlatb ; new char is in al
- atnrm14:cmp al,DEL ; ANSI Delete char?
- jne atnrm2 ; ne = no
- ret ; ignore DEL
- ; use atdeb for debug simple tty dsp
- atnrm2: mov dx,cursor ; get cursor virtual position
- push bx
- mov bl,dh ; get row
- xor bh,bh
- mov bl,linetype[bx] ; line width
- mov thisline,bl ; save for current reference
- pop bx
- test vtemu.vtflgop,decawm ; Autowrap active?
- jz atnrm2a ; z = no
- mov cl,mar_right ; logical right margin
- cmp thisline,0 ; single width line?
- je atnrm2c ; e = yes, single
- test flags.vtflg,ttd463+ttd470 ; D463/D470?
- jnz atnrm2c ; nz = yes, these double the margins
- shr cl,1 ; halve right column # for wide chars
- atnrm2c:cmp dl,cl ; want to write beyond right margin?
- jb atnrm2a ; b = no
- cmp atwrap,0 ; autowrap pending?
- je atnrm2a ; e = no
- test anspflg,vtautop ; printing desired?
- jz atnrm2a ; e = no
- push dx
- push ax ; save char
- mov dh,atwrap ; get 1+last display line's row
- dec dh ; up one line
- call pntlin ; print line
- mov al,LF ; terminate in LF
- call fpntchr
- call fpntflsh ; flush printer buffer
- pop ax ; recover char in AL
- pop dx
- atnrm2a:push ax ; save character
- call getatch ; check for protected field
- test cl,att_protect ; protected?
- jz atnrm2d ; z = no
- test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jz atnrm2d ; z = no
- call dgcuf ; do DG cursor right
- mov dx,cursor
- atnrm2d:cmp decrlm,0 ; host right-left mode active?
- je atnrm2e ; e = no
- cmp atwrap,0 ; wrap pending?
- je atnrm2e ; e = no
- mov dl,mar_right
- inc dl ; set to wrap in normal sense
-
- atnrm2e:call atscur ; set cursor physical position
- pop ax
- cmp insmod,0 ; insert mode off?
- je atnrm3 ; e = yes
- push ax
- call inschr ; open a char space in this line
- cmp thisline,0 ; single width line?
- je atnrm2b ; e = yes
- call inschr ; open second space for double width
- atnrm2b:pop ax ; restore char
- ; set cursor before writing char
- atnrm3: cmp thisline,0 ; check for double characteristic
- je atnrm3a ; e = normal, not doubles
- shl dl,1 ; double the column number
- atnrm3a:
- push dx
- call direction ; set dx to desired position
- mov ah,curattr ; current attribute
- mov cl,extattr ; extended attribute
- call setatch ; write char (al) and attribute (ah)
- pop dx
- cmp thisline,0 ; check for double characteristic
- je atnrm4 ; e = normal, not doubles
- cmp decrlm,0 ; host writing direction active?
- je atnrm3b ; e = no
- dec dl ; next col
- jmp short atnrm3c
- atnrm3b:inc dl ; next column
- atnrm3c:push dx
- call direction ; set dx to desired position
- mov al,' ' ; use a space for doubling
- mov ah,curattr ; current attribute
- mov cl,extattr ; extended attribute
- call setatch ; write char (al) and attribute (ah)
- pop dx
- shr dl,1 ; keep "cursor" in single units
-
- atnrm4: test flags.vtflg,ttd463+ttd470+ttheath ; D463, D470 or H-19?
- jz atnrm4d ; z = no
- jmp dgcuf ; do DG cursor forward
-
- atnrm4d:test vtemu.vtflgop,decawm ; Autowrap active?
- jz atnrm5 ; z = no
- cmp decrlm,0 ; host writing left to right?
- je atnrm4e ; e = no
- or dl,dl ; wrote in left most col?
- jnz atnrm5 ; nz = no
- mov dl,mar_right ; set next column to the right
- jmp short atnrm4b ; do not move cursor now
-
- atnrm4e:mov cl,mar_right ; logical right margin
- cmp thisline,0 ; single width line?
- je atnrm4a ; e = yes, single
- shr cl,1 ; halve right column # for wide chars
- atnrm4a:cmp dl,cl ; wrote in right-most column?
- jb atnrm5 ; b = no
- inc dl ; say want to use next column
- atnrm4b:mov atwrap,dh ; turn on wrap flag with 1 + this row
- inc atwrap ; so 0 means no wrap pending
- test flags.vtflg,ttheath ; H-19?
- jnz atscur ; nz = yes, show wrap now
- mov cursor,dx ; virtual cursor position
- ret ; exit without moving cursor from eol
-
- atnrm5: mov dx,cursor ; restore cursor position
- cmp decrlm,0 ; host writing direction active?
- je atnrm5a ; e = no
- or dl,dl
- jz atnrm5b
- dec dl ; next column
- jmp short atnrm5b
- atnrm5a:inc dl ; next column
- atnrm5b:mov atwrap,0 ; say not about to wrap
- ;; jmp short atscur
- atnrm endp
-
- atscur: cmp dl,mar_left ; left of left margin?
- jae atscu1 ; ae = no, continue
- mov dl,mar_left ; set at left margin
- atscu1: mov cl,mar_right ; copy logical margin; cl = right col
- push bx
- mov bl,dh ; get row
- xor bh,bh
- cmp linetype [bx],0 ; single width lines?
- pop bx
- je atscu1a ; e = yes, single width
- test flags.vtflg,ttd463+ttd470 ; D463/D470?
- jnz atscu1a ; nz = yes, these double the margins
- shr cl,1 ; halve column # for double wides
- atscu1a:cmp dl,cl ; right of right margin?
- jbe atscu3 ; be = no, continue
- mov dl,cl ; assume no autowrap
- test vtemu.vtflgop,decawm ; Autowrap?
- jz atscu3 ; z = no
- mov dl,mar_left ; set to left margin
- cmp decrlm,0 ; host right-left mode active?
- je atscu1e ; e = no
- mov dl,mar_right
- atscu1e:cmp dh,byte ptr low_rgt+1 ; at bottom of screen?
- je atscu1b ; e = yes
- cmp dh,mar_bot ; at bottom of scrolling region?
- jl atscu2 ; l = no, bump cursor and continue
- atscu1b:test flags.vtflg,ttd463+ttd470 ; D463/D470?
- jz atscu1d ; z = no
- cmp dgroll,0 ; is DG roll enabled?
- jne atscu1d ; ne = yes, do the scroll
- mov dh,mar_top ; move to top of window
- jmp short atscu3
- atscu1d:mov scroll,1 ; scroll count = 1 line
- call atscru ; scroll up
- dec dh ; offset inc dh below
- atscu2: inc dh ; just bump it
- atscu3: or dh,dh ; constrain row to valid range
- jge atscu4 ; ge = non-negative row, ok
- xor dh,dh
- atscu4: cmp dh,byte ptr low_rgt+1 ; 25th line?
- jle atsetcur ; le = no
- mov dh,byte ptr low_rgt+1 ; set to 24th line
- cmp flags.vtflg,ttheath ; emulating a Heath-19?
- jne atscu4a ; ne = no [hlk]
- test h19stat,h19l25 ; Heath 25th line enabled?
- jz atsetcur ; z = no
- atscu4a:inc dh ; go to line 25 [hlk]
- test yflags,modoff ; is mode line off?
- jnz atscu4b ; nz = yes
- push dx ; save cursor position
- call fclrmod ; clear the line
- or yflags,modoff ; now say it's off (owned by host)
- pop dx
- atscu4b:mov flags.modflg,2 ; say mode line is owned by host
-
- atsetcur:mov cursor,dx ; set cursor and return
- push dx
- mov bl,dh ; get row
- xor bh,bh ; clear high byte
- cmp linetype[bx],0 ; single width line?
- je atsetcu1 ; e = yes
- shl dl,1 ; double the column number
- atsetcu1:call direction ; set dx to desired position
- call setpos ; set cursor physical position
- pop dx
- test vtemu.vtflgop,vsmarginbell; do we care about margin bell?
- jz atsetcu2 ; z = no, return if no margin bell
- cmp kbiflg,0 ; is keyboard input flag set?
- je atsetcu2 ; e = no, just return
- mov bx,kbicsr ; cursor at previous keyboard input
- cmp bh,dh ; same row as now?
- jne atsetcu2 ; ne = no, just return
- cmp bl,belcol ; old cursor at or left of bell column?
- ja atsetcu2 ; a = no, just return
- cmp dl,belcol ; new cursor past bell column?
- jbe atsetcu2 ; be = no, just return
- call vtbell ; ring the bell
- atsetcu2:ret
-
- ; Control-character dispatcher
- atctrl: cmp al,escape ; an escape sequence starting?
- je atctrl1 ; e = yes, don't print it
- cmp al,CSI ; this kind of escape?
- je atctrl1 ; e = yes
- cmp al,18h ; CAN (cancel)?
- je atctrl6 ; e = yes
- cmp al,1ah ; SUB (treated as CAN)?
- je atctrl6 ; e = yes
- cmp ttstate,offset atdcsnul ; consuming a DCS?
- jne atctrl5 ; ne = no
- ret ; consume
- atctrl5:cmp ttstate,offset atesc1 ; state is second char of ST?
- jne atctrl6 ; ne = no
- jmp ttstate ; go process second char
- atctrl6:test anspflg,vtcntp ; printing desired?
- jz atctrl1 ; z = no
- call fpntchr ; print char in al
- atctrl1:xor ah,ah ; clear for word use below
- test al,80h ; high bit set?
- jnz atctrl2 ; nz = yes
- mov di,ax ; use AL as a word index
- shl di,1
- atctrl3:jmp ansc0[di] ; dispatch on C0 control codes
- atctrl2:and al,not 80h ; strip high bit
- mov di,ax ; use AL as a word index
- shl di,1
- test flags.vtflg,ttvt320+ttvt220 ; doing VT320/VT220?
- jz atctrl3 ; z = no, trim back to C0
- atctrl4:jmp ansc1[di] ; dispatch on C1 control codes
-
- ; Control code routines
- atbs: cmp decrlm,0 ; host writing direction active?
- jne atbs2 ; ne = yes
- or dl,dl ; Backspace, too far?
- jz atbs1 ; z = at column 0 already
- dec dl ; backup cursor
- atbs1: call atccpc ; check range
- mov atwrap,0 ; cancel wrap pending
- jmp atsetcur ; set cursor and return
-
- atbs2: cmp dl,mar_right ; at right margin now?
- je atbs1 ; e = yes, stop
- inc dl
- jmp short atbs1
-
- atht: cmp flags.vtflg,ttheath ; Horizontal Tab, Heath-19 mode?
- je atht2 ; e = yes, handle specially
- xor ch,ch
- mov cl,mar_right
- cmp dl,cl ; at or beyond last column?
- jae atht1a ; ae = yes check range, set cursor
- atht1: inc dl ; tab always moves at least one column
- push si
- mov si,vtemu.vttbst ; active buffer
- call istabs ; returns carry set if at a tabstop
- pop si
- jc atht1a ; c = at a tabstop
- loopz atht1
- atht1a: call atccpc ; check range
- atht1b: call atsetcur ; set cursor and return
- ret
-
- atht2: mov dx,cursor ; Heath-19. get cursor position
- add dl,8 ; tabs are every 8 columns
- and dl,not 7 ; do modulo 8
- cmp dl,mar_right ; check against right edge
- jbe atht3 ; be = in range
- mov dl,mar_right ; else go to right margin
- atht3: jmp atht1b ; set cursor and return
-
- atlf: test vtemu.vtflgop,anslnm ; Line Feed, New-line mode?
- jz atlf2 ; z = no, just move to next line down
- atlf1: mov dl,mar_left ; move to left margin also
- cmp decrlm,0 ; host writing direction active?
- je atlf2 ; e = no
- mov dl,mar_right
- atlf2: test anspflg,vtautop ; printing desired?
- jz atlf3 ; e = no
- push dx
- push ax ; save char
- call pntlin ; print current line
- pop ax ; recover char in AL, print it too
- call fpntchr
- call fpntflsh ; flush printer buffer
- pop dx
- atlf3: inc dh ; index line down
- call atccic ; check indexing
- call ax ; call scrolling routine
- jmp atsetcur ; set cursor
-
- atcr: mov dl,mar_left ; Carriage Return, go to left margin
- mov atwrap,0 ; cancel wrap pending
- cmp decrlm,0 ; host writing direction active?
- je atcr2 ; e = no
- mov dl,mar_right
- atcr2: cmp flags.vtflg,ttheath ; Heath-19?
- jne atcr1 ; ne = no
- test h19stat,h19alf ; auto line feed on?
- jnz atlf2 ; nz = yes, do the LF part above
- atcr1: jmp atsetcur ; set cursor and return
-
- atff: cmp ttstate,offset atescf ; Form Feed, parsing escape sequence?
- jne atlf ; ne = no, do as line feed
- atff1: test denyflg,tekxflg ; is auto Tek mode disabled?
- jnz atlf ; nz = yes, treat as line feed
- call atsc ; save cursor and associated data
- mov al,escape
- call TEKEMU
- mov al,FF
- call TEKEMU ; feed to Tektronix Emulator, al=FF
- jmp atnorm
-
- atcan: mov parstate,0 ; CAN, clear esc seq parser
- jmp atnorm
-
- atenq: mov cx,ENQhstrl ; length of Honeywell string
- mov si,offset ENQhstr ; ptr to string
- mov ttyact,0 ; start grouping for networks
- cmp flags.vtflg,tthoney ; ENQ, Honeywell terminal?
- je atenq1 ; e = yes
- cmp vtenqenable,0 ; VTxxx response enabled?
- je atenq2 ; e = no
- mov cx,ENQstrl ; length of string
- mov si,offset ENQstr ; ptr to string
- atenq1: cld
- lodsb ; get a byte
- push cx ; save regs
- push si
- call prtbout ; send to port WITHOUT echo
- pop si
- pop cx
- loop atenq1 ; loop for all characters
- mov ttstate, offset atnrm ; reset to normal and return
- mov ttyact,1 ; end group output for networks
- atenq2: ret
-
- atesc: cmp ttstate,offset atdcsnul ; consuming a DCS?
- jne atesc3 ; ne = no
- mov ttstate,offset atesc1 ; stay here
- ret
- atesc1: cmp al,'\' ; end of ST?
- je atesc2 ; e = yes
- jmp atdcsnul ; continue to consume DCS
- atesc2: jmp atgotst ; reset DCS processing
-
- atesc3: mov ttstate,offset atescf ; ESC, next state is escape follower
- ret
-
- ; Respond to character following Escape, dispatch on that char
- atescf: call atpclr ; clear parser argument list
- mov atescftab,offset ansesc; ANSI escape table, for atdispat
- mov cx,flags.vtflg
- test cx,ttvt320+ttvt220+ttvt102+ttvt100+tthoney ; VT320 etc?
- jnz atescf2 ; nz = yes
- mov atescftab,offset v52esc ; VT52 escape table
- cmp cx,ttvt52 ; VT52?
- je atescf1 ; e = yes
- mov atescftab,offset h19esc ; use Heath-19 table
- cmp cx,ttheath ; Heath-19?
- je atescf1 ; e = yes
- mov atescftab,offset pt200esc
- cmp cx,ttpt200 ; Prime PT200?
- je atescf2 ; e = yes
- ret ; return on error
- atescf1:mov ttstate,offset atnrm ; reset state to "normal"
- mov bx,atescftab ; get offset of escape follower table
- jmp atdispat ; perform dispatch via table in BX
-
- atescf2:test al,not (2fh) ; in intermediates (column 2)?
- jnz atescf1 ; nz = no, dispatch on this char
- mov ttstate,offset atescf2 ; stay in this state til col 3 or more
- mov bx,ninter ; number of intermediates
- cmp bx,maxinter ; done enough already?
- jae atescf3 ; ae = yes, ignore the excess
- mov inter[bx],al ; store this one
- inc ninter ; one more
- atescf3:ret ; get more input
-
- ; CSI, char 9bh (ANSI CSI == ESC [)
- atcsi0: cmp ninter,0 ; any intermediates from ESC..[?
- je atcsi ; e = no, else not this item
- jmp atnorm ; reset state to "normal"
- ; enter here with real CSI char
- atcsi: mov ttstate,offset atparse ; next state is parse control seq
- mov pardone,offset atcsi1 ; where to jmp when done
- mov parfail,offset atnorm ; where to jmp if failure
- jmp atpclr ; clear parser parameters and return
-
- atcsi1: mov bx,offset anstab ; ANSI Final character table
- mov ttstate,offset atnrm ; reset state to "normal"
- jmp atdispat ; dispatch on character
-
- h19csi: test vtemu.vtflgop,decanm ; Heath-19 "ESC [", is ANSI mode on?
- jnz h19csi1 ; nz = yes
- mov ttstate,offset atnrm ; else ignore the "[" (kbd lock)
- ret
- h19csi1:mov ttstate,offset atparse ; H-19, ESC [ parser
- mov pardone,offset h19csi2 ; where to jmp when done
- mov parfail,offset atnorm ; where to jmp if failure
- ret ; get next char
- h19csi2:mov bx,offset h19ans ; H-19 ANSI Final character table
- mov ttstate,offset atnrm ; reset state to "normal"
- jmp atdispat ; dispatch on character
-
- ; Process Device Control Strings (DCS or ESC P lead-in chars, already read).
- atdcs0: cmp ninter,0 ; any intermediates?
- je atdcs ; e = no, else not this item
- jmp atnorm ; reset state to normal
- ; enter here with real DCS char
- atdcs: mov ttstate,offset atparse ; next state is parse control seq
- mov pardone,offset atdcs1 ; where to jmp when done
- mov parfail,offset atnorm ; where to jmp if failure
- ret
- atdcs1: mov dcsstrf,al ; record Final char
- mov emubufc,0 ; clear string count
- mov cx,maxparam ; number of DCS parameters
- push si ; copy these to the DCS area so that
- push di ; they are not lost when an ST is
- push es ; parsed (parser clears ESC items)
- push ds
- pop es
- mov si,offset param ; ESC paramater storage area, numeric
- mov di,offset dparam ; DCS parameter storage area, numeric
- cld
- rep movsw ; copy set to DCS storage area
- mov cl,lparam ; copy letter Paramter
- mov dlparam,cl
- mov cx,maxinter ; number of intermediate characters
- mov si,offset inter ; source
- mov di,offset dinter ; destination
- rep movsb
- mov si,nparam ; number of parameters
- mov dnparam,si
- mov si,ninter
- mov dninter,si ; number of intermediates
- pop es
- pop di
- pop si
- mov ttstateST,offset atnorm ; default ST completion state
- mov emubufc,0 ; clear processed string length
- mov al,dcsstrf ; get DCS Final char
- mov bx,offset dcstab ; DCS dispatch table
- call atdispat ; go to DCS handler
- ret
-
- ; Process ST or ESC \ String Terminator.
- atgotst0:cmp ninter,0 ; any intermediates in ESC..\?
- je atgotst ; e = no, else not this item
- jmp atnorm ; reset state to normal
- ; enter here with real ST char
- atgotst:jmp ttstateST ; go to state for ST arrival
-
- ; Read and discard OSC (ESC ]), PM (ESC ^) control sequences
- ; through final ST (ESC \) terminator.
- atdcsnul0:cmp ninter,0 ; any intermediates in ESC..\?
- je atdcsnul ; e = no, else not this item
- ret
- ; enter here with real ST char
- atdcsnul:mov dcsstrf,0 ; simulate a null (dummy) Final char
- mov emubufc,0 ; clear string count
- mov ttstate,offset atdcsnul ; keep coming here
- mov ttstateST,offset atnorm ; where to go when ST has been seen
- ret ; consume chars
-
- ; Process Application Process Control string (APC or ESC _ lead-in chars,
- ; already read). Mallocs 1KB buffer, passes buffer to apcmacro for execution
- ; as a Take file. Curly braces protect comma command separators.
- atapc: cmp ninter,0 ; any intermediates?
- je atapc0 ; e = no, else not this item
- jmp atnorm ; reset state to normal
- ; enter here with real DCS char
- atapc0: mov ax,apcstring ; old string buffer segment
- or ax,ax ; used?
- jz atapc1 ; z = no
- push es
- mov es,ax
- mov ah,freemem ; free that string memory
- int dos
- pop es
- mov apcstring,0 ; clear pointer
- atapc1: mov bx,(1024+3+15)/16 ; 1K buffer
- mov cx,bx ; remember desired paragraphs
- mov ah,alloc ; allocate a memory block
- int dos
- jc atapc2 ; c = error, not enough memory
- cmp bx,cx ; obtained vs wanted
- jae atapc3 ; ae = enough
- push es
- mov es,ax ; allocated segment
- mov ah,freemem ; free it again
- int dos
- pop es
- atapc2: jmp atnorm ; fail
-
- atapc3: mov apcstring,ax ; remember segment
- mov bracecount,0 ; count of curly braces in string
- mov emubufc,0 ; preset string buffer count
- mov ttstate,offset atapc4 ; next state is read string
- mov ttstateST,offset atapc5 ; where to go when ST has been seen
- ret
- ; read bytes of APC string
- atapc4: mov bx,emubufc ; count of buffer chars
- cmp bx,1024 ; too many?
- ja atapc6 ; a = yes, ignore string
- push es
- mov cx,apcstring ; segment of string buffer
- mov es,cx
- cmp al,braceop ; opening brace?
- jne atapc4a ; ne = no
- inc bracecount ; count up braces
- atapc4a:cmp al,bracecl ; closing brace?
- jne atapc4b ; ne = no
- sub bracecount,1 ; count down braces
- jnc atapc4b ; nc = not below zero
- mov bracecount,0 ; clamp to zero
- atapc4b:cmp al,',' ; comma command separator?
- jne atapc4c ; ne = no
- cmp bracecount,0 ; in curly braces?
- jne atapc4c ; ne = yes, leave comma as comma
- mov al,CR ; replace bare comma as CR
- atapc4c:xor ah,ah
- mov es:[bx],ax ; store incoming byte + null
- pop es
- inc emubufc ; count bytes in buffer
- ret ; accumulate more bytes
-
- atapc5: mov ax,apcstring ; get here upon ST for APC
- or ax,ax ; string buffer in use?
- jz atapc6 ; z = no, quit
- mov ttstate,offset atnrm ; reinit state before leaving
- mov ttstateST,offset atnorm
- mov bracecount,0 ; count of curly braces in string
- cmp apcenable,0 ; is APCMACRO enabled?
- je atapc6 ; e = no, quit
- push es
- mov es,ax
- mov bx,emubufc ; count of bytes in string
- mov byte ptr es:[bx],CR ; append CR C to renter Connect mode
- mov byte ptr es:[bx+1],'C'
- add bx,2 ; two more bytes in buffer
- pop es
- mov cx,bx ; CX used to pass string length
- call APCMACRO ; create and execute Take file
- ; does not return if success
- atapc6: mov ax,apcstring ; segment of string buffer
- or ax,ax ; in use?
- jz atapc7 ; z = no
- mov es,ax
- mov ah,freemem ; free buffer
- int dos
- atapc7: mov apcstring,0 ; clear buffer
- mov emubufc,0 ; clear string count
- mov bracecount,0 ; count of curly braces in string
- jmp atnorm ; exit this sequence
-
-
- ; User Definable Key processor of DCS strings.
- atudk: cmp dinter,0 ; no intermediates?
- je atudk1 ; e = correct
- mov ninter,0 ; setup atdcsnul for proper form
- jmp atdcsnul ; bad, consume the rest
-
- atudk1: cmp dparam,1 ; is initial Parameter Pc a 1?
- jae atudk2 ; ae = yes, clear only this key
- call udkclear ; clear all UDKeys
- mov dparam,1 ; and turn off Parameter
- atudk2: mov ttstate,offset atudk3 ; next state is get a substring
- mov ttstateST, offset atudk6 ; for when ST has been seen
- ret
-
- atudk3: cmp al,';' ; string separator?
- je atudk5 ; e = yes, process string to-date
- mov bx,emubufc ; count of chars in string buffer
- cmp bx,emubufl ; too many?
- jae atudk4 ; ae = too many, ignore extras
- mov emubuf[bx],al ; store the char
- inc emubufc ; count it
- atudk4: ret
- atudk5: mov si,offset emubuf ; address of string buffer is DS:SI
- mov cx,emubufc ; count of buffer contents
- call setudk ; insert string definition
- mov emubufc,0 ; clear string buffer
- ret
- atudk6: call atudk5 ; ST seen, process last string
- jmp atnorm ; reset state to normal
-
- ; Call this routine to deliver Parameters in succession. Each call points to
- ; a Parameter as param[si], where si is maintained here. If there are no
- ; Parameters the effect is the same as one Parameter with a value of zero.
- ; Enter with di = offset of action routine to be called for each Parameter.
- ; cx, si, and di are preserved over the call to the action routine.
-
- atreps proc near
- xor si,si ; initialize parm index
- mov cx,nparam ; number of Parameters
- or cx,cx ; zero?
- jnz atrep1 ; nz = no
- inc cx ; zero parms is same as 1
- atrep1: push cx ; save loop counter
- push si ; save parameter index
- push di ; save call vector
- call DI ; call indicated routine
- pop di ; restore registers
- pop si
- pop cx
- add si,2 ; advance to next parameter
- loop atrep1 ; loop for all
- ret
- atreps endp
-
- ; Action routines
- atind0: cmp ninter,0 ; any intermediates?
- je atind ; e = no, else not this item
- ret
- atind: inc dh ; IND (index), move cursor down one
- atind1: call atccic ; check cursor position
- call ax ; scroll if necessary
- jmp atsetcur ; set cursor, etc. and return
-
- atnel0: cmp ninter,0 ; any intermediates from ESC..E?
- je atnel ; e = no, else not this item
- jmp atdgnrc ; try Nowegian/Danish NRC designator
- ; enter here with real NEL char
- atnel: mov dl,mar_left ; NEL, next line - sort of like CRLF
- inc dh ; ... all in one command
- jmp short atind1 ; check cursor, etc., and return
-
- atri0: cmp ninter,0 ; any intermediates?
- je atri ; e = no, else not this item
- ret
- atri: cmp flags.vtflg,ttheath ; Heath-19?
- jne atri1 ; ne = no
- cmp dh,byte ptr low_rgt+1 ; on 25th line?
- jbe atri1 ; be = no
- ret ; no vertical for Heath on 25th line
- atri1: dec dh ; RI, reverse index
- jmp short atind1 ; check cursor, etc., and return
-
- ; HTS, horizontal tab set in this col
- athts0: cmp ninter,0 ; any intermediates from ESC..H?
- je athts ; e = no, else not this item
- jmp atdgnrc ; try Swedish NRC designator
- athts: call atccpc ; make column number valid
- mov si,vtemu.vttbst ; active buffer
- jmp tabset ; say set tab in this column (DL)
-
- ; DECSC
- atsc: mov si,offset savelist ; save cursor, attribute, char set etc
- mov di,offset savecu ; place to save the stuff
- mov cl,extattr ; extended attributes
- mov savextattr,cl ; it's real storage is in msyibm
- mov cl,scbattr
- mov savscbattr,cl
- mov havesaved,1 ; say have saved something
- mov cx,lsavecu ; length of save area
- push es ; save es
- mov ax,data ; seg of save area
- mov es,ax ; set es to data segment
- cld
- shr cx,1 ; divide by two for word moves
- jnc atsc1 ; nc = even number of bytes
- movsb ; do the odd byte
- atsc1: rep movsw ; save it
- pop es
- mov cx,vtemu.vtflgop ; save a copy of the flags
- mov savflgs,cx
- ret
- ; DECRC
- atrc: cmp havesaved,0 ; saved anything yet?
- jne atrc1 ; ne = yes
- ret
- atrc1: mov si,offset savecu ; restore cursor, attributes, etc
- mov di,offset savelist ; where stuff goes
- mov cx,lsavecu ; length of save area
- push es ; save es
- push ds
- mov ax,seg savecu ; seg of savecu storage
- mov ds,ax
- mov ax,seg savelist ; seg of regular storage
- mov es,ax
- cld
- shr cx,1 ; divide by two for word moves
- jnc atrc2 ; nc = even number of bytes
- movsb ; do the odd byte
- atrc2: rep movsw ; put the stuff back
- pop ds
- pop es
- mov al,savextattr ; extended attributes
- mov extattr,al
- mov al,savscbattr
- mov scbattr,al
- mov ax,savflgs ; get saved flags
- xor ax,vtemu.vtflgop ; exclusive-or with current flags
- mov al,atctype ; get cursor shape
- call csrtype ; restore it
- atrc3: mov ax,vtemu.vtflgop ; reset flags in case called again
- and ax, not(decckm+deckpam+decom) ; remove old bits [dlk]
- and savflgs,(decckm+deckpam+decom) ; remove all but new bits [dlk]
- or ax,savflgs ; restore saved bits [dlk]
- or vtemu.vtflgop,ax ; update these flags
- mov savflgs,ax
- mov bx,offset Gsetid ; restore character sets
- call chrsetup ; go remake G0..G3
- mov dx,cursor ; get cursor
- mov kbiflg,0 ; don't bother them with beeps here
- jmp atsetcur ; set cursor
-
- atkpam: cmp ninter,0 ; any intermediates?
- jne atkpam1 ; ne = yes, not this item
- or vtemu.vtflgop,deckpam ; turn on keypad applications mode
- ret
- atkpam1:jmp atdgnrc ; try Swiss NRC designator
-
- atkpnm: and vtemu.vtflgop,not deckpam ; turn off keypad applications mode
- ret ; (to numeric mode)
-
- ; Privileged sequence, ignore it
- atpriv: cmp ninter,0 ; any intermediates?
- jne atpriv1 ; ne = yes, not this item
- mov ttstate,offset atnorm ; ignore next char
- atpriv1:ret ; and return to normal afterward
-
- ; ISO 2022 three byte Announcer Summary <ESC> <space> <final char>
- ;Esc Sequence 7-Bit Environment 8-Bit Environment
- ;---------- ------------------------ ----------------------------------
- ;<ESC><SP>A G0->GL G0->GL
- ;<ESC><SP>B G0-(SI)->GL, G1-(SO)->GL G0-(LS0)->GL, G1-(LS1)->GL
- ;<ESC><SP>C (not used) G0->GL, G1->GR
- ;<ESC><SP>D G0-(SI)->GL, G1-(SO)->GL G0->GL, G1->GR
- ;<ESC><SP>E Full preservation of shift functions in 7 & 8 bit environments
- ;<ESC><SP>F C1 represented as <ESC>F C1 represented as <ESC>F
- ;<ESC><SP>G C1 represented as <ESC>F C1 represented as 8-bit quantity
- ;<ESC><SP>H All graphic character sets have 94 characters
- ;<ESC><SP>I All graphic character sets have 94 or 96 characters
- ;<ESC><SP>J In a 7 or 8 bit environment, a 7 bit code is used
- ;<ESC><SP>K In an 8 bit environment, an 8 bit code is used
- ;<ESC><SP>L Level 1 of ISO 4873 is used
- ;<ESC><SP>M Level 2 of ISO 4873 is used
- ;<ESC><SP>N Level 3 of ISO 4873 is used
- ;<ESC><SP>P G0 is used in addition to any other sets:
- ; G0 -(SI)-> GL G0 -(LS0)-> GL
- ;<ESC><SP>R G1 is used in addition to any other sets:
- ; G1 -(SO)-> GL G1 -(LS1)-> GL
- ;<ESC><SP>S G1 is used in addition to any other sets:
- ; G1 -(SO)-> GL G1 -(LS1R)-> GR
- ;<ESC><SP>T G2 is used in addition to any other sets:
- ; G2 -(LS2)-> GL G2 -(LS2)-> GL
- ;<ESC><SP>U G2 is used in addition to any other sets:
- ; G2 -(LS2)-> GL G2 -(LS2R)-> GR
- ;<ESC><SP>V G3 is used in addition to any other sets:
- ; G3 -(LS2)-> GL G3 -(LS3)-> GL
- ;<ESC><SP>W G3 is used in addition to any other sets:
- ; G3 -(LS2)-> GL G3 -(LS3R)-> GR
- ;<ESC><SP>Z G2 is used in addition to any other sets:
- ; SS2 invokes a single character from G2
- ;<ESC><SP>[ G3 is used in addition to any other sets:
- ; SS3 invokes a single character from G3
- ;
- ; ISO Escape Sequences for Alphabet Designation ("F" = Final char)
- ; Sequence Function Invoked By
- ; <ESC>(F assigns 94-character graphics set "F" to G0. SI or LS0
- ; <ESC>)F assigns 94-character graphics set "F" to G1. SO or LS1
- ; <ESC>*F assigns 94-character graphics set "F" to G2. SS2 or LS2
- ; <ESC>+F assigns 94-character graphics set "F" to G3. SS3 or LS3
- ; <ESC>-F assigns 96-character graphics set "F" to G1. SO or LS1
- ; <ESC>.F assigns 96-character graphics set "F" to G2. SS2 or LS2
- ; <ESC>/F assigns 96-character graphics set "F" to G3. SS3 or LS3
- ; <ESC>$(F assigns multibyte character set "F" to G0. SI or LS0
- ; <ESC>$)F assigns multibyte character set "F" to G1. SO or LS1
- ; <ESC>$*F assigns multibyte character set "F" to G2. SS2 or LS2
- ; <ESC>$+F assigns multibyte character set "F" to G3. SS3 or LS3
- ;
- ; Designate character sets, AL has final character, inter has all preceeding.
-
- atdgfA: call atdgset ; 'A' ISO Latin-1, UK-ASCII
- jc atdgfA1 ; c = no matching pointer
- cmp inter,'+' ; in the 94 byte set?
- ja atdgfA2 ; a = no, 96 'A' is Latin1
- mov ax,flags.vtflg ; terminal type
- test ax,ttvt320+ttvt220+ttvt102+ttvt100+tthoney ; VTxxx?
- jz atdgfA1 ; z = no
- jmp mkukascii ; make UK ASCII table
- atdgfA1:ret
-
- atdgfA2:jmp mklatin1 ; make Latin1 char set
-
- atdgfA3:jmp atdgnrc ; try British NRC
-
- atdgfB: call atdgset ; 'B' ASCII, get setptr from inter
- jc atdgfA1 ; c = no matching pointer
- cmp inter,'+' ; in the 94 byte set?
- ja atdgfB1 ; a = no, do Latin2
- jmp mkascii ; make US ASCII set
- atdgfB1:jmp mklatin2 ; make Latin2 ("B"/96)
-
- atdgf0: call atdgset ; '0', '2', DEC Special Graphics
- jc atdgfA1 ; c = no matching pointer
- cmp inter,'+' ; in the 94 byte set?
- ja atdgfA1 ; a = no, ignore
- jmp mkdecspec ; init set to DEC Special Graphics
-
- atdgf1: call atdgset ; '1' ALT-ROM
- jc atdgf1b ; c = no matching pointer
- jmp mkaltrom ; make ALT-ROM set
-
- atdgf1b:
- ; cmp ninter,0 ; ESC 1? (Special enter Tek mode)
- ; jne atdgf1c ; ne = some, not ESC 1
- ; cmp nparam,0
- ; jne atdgf1c ; ne = some, not ESC 1
- ; jmp atff1 ; treat the same as ESC ^L
- atdgf1c:ret
-
- atdgft: call atdgset ; '>' Dec Technical Set
- jc atdgft1 ; c = no matching pointer
- cmp inter,'+' ; in the 94 byte set?
- ja atdgft1 ; a = no
- jmp mkdectech ; make DEC Tech set
-
- atdgft1:cmp ninter,0 ; ESC > DECKNPNM set numeric keypad?
- jne atdgft2 ; ne = no
- and vtemu.vtflgop,not deckpam ; turn off application keypad bit
- atdgft2:ret ; (to numeric)
- ; '<' User Preferred Supplemental Set
- atdgfu: call atdgset ; get set pointer
- jc atdgfu2 ; c = no matching pointer
- cmp inter,',' ; designating the 96 char set?
- jb atdgfu1 ; b = no, want 94
- cmp word ptr upss+1,0+'A' ; is ISO Latin-1 the preferred set?
- jne atdgfu0a ; ne = no
- jmp mklatin1 ; make Latin1 set
- atdgfu0a:cmp word ptr upss+1,0+'H' ; is Hebrew-ISO preferred?
- jne atdgfu2 ; ne = no
- jmp mklatin_Hebrew ; make Hebrew-ISO
-
- atdgfu1:cmp word ptr upss+1,'5%' ; DEC Supplemental Graphics?
- jne atdgfu1a ; ne = no
- jmp mkdecmn ; make DEC Multinat/Supp Gr
- atdgfu1a:cmp word ptr upss+1,'4"' ; DEC Hebrew?
- jne atdgfu2
- jmp mkdec_Hebrew ; make DEC Hebrew
- atdgfu2:ret
-
- atdgfq: call atdgset ; '?' Transparent
- jc atdgfu2 ; c = no matching pointer
- jmp mkxparent ; make transparent table
-
- ; ESC <...> <1-8> series
- atsdhl: cmp ninter,1 ; just one intermediate?
- jne atsdh0 ; ne = no
- cmp inter,'#' ; this intermediate?
- jne atdgnrc ; ne = no, try NRC char set designator
- cmp al,'3' ; Double high lines. Top half?
- je atsdh2 ; e = yes
- cmp al,'4' ; bottom half?
- je atsdh2 ; e = yes
- cmp al,'5' ; restore line to single width?
- je atsdh1 ; e = yes
- cmp al,'6' ; double width single height?
- je atsdh2 ; e = yes
- cmp al,'8' ; screen alignment?
- je atsdh8 ; e = yes
- atsdhx: ret ; else ignore
-
- atsdh1: jmp linesgl ; set line to single width
- atsdh2: jmp linedbl ; expand the line to double width
- atsdh8: jmp atalign ; do screen alignment
-
- atsdh0: cmp ninter,0 ; zero intermediates?
- jne atdgf5 ; ne = no, try for more
- cmp al,'7' ; save cursor?
- jne atsdh0a ; ne = no
- jmp atsc ; do save cursor, ESC 7
- atsdh0a:cmp al,'8' ; restore cursor?
- jne atsdh0b ; ne = no
- jmp atrc ; do restore cursor, ESC 8
- atsdh0b:ret
-
- atdgf5: cmp ninter,2 ; two intermediates?
- jne atdgf5a ; ne = no, ignore remainder
- cmp al,'6' ; '%6' NRC designator?
- je atdgnrc ; e = yes, do that above
- cmp al,'5' ; '%5' DEC Supplemental Graphic?
- jne atdgf5a ; ne = no
- cmp inter,'+' ; in the 94 byte set?
- ja atdgf5a ; a = no, ignore
- cmp inter[1],'%' ; '%5'?
- jne atdgf5a ; ne = no
- mov ninter,1 ; help atdgset find our set
- call atdgset ; get set pointer
- jc atdgf5a ; c = no matching pointer
- jmp mkdecmn ; make DEC Multinat/Supp Gr
- atdgf5a:ret
-
- ; Enter with Final esc char in al, others in array inter. Setup Gn if success.
- atdgnrc proc near ; check for NRC set designator
- cmp ninter,0 ; ESC Z?
- jne atdgnr1 ; ne = no
- cmp al,'Z' ; the Z?
- jne atdgnrx ; ne = not ESC Z
- jmp atda ; process ident request
- atdgnr1:cmp inter,'+' ; in the 94 byte set?
- ja atdgnrx ; a = no, ignore
- call findctry ; find NRC country number in CX
- jc atdgnrx ; c = not found, ignore
- mov ninter,1 ; help atdgset find our set
- call atdgset ; check for Gn designator
- jc atdgnrx ; c = not found
- jmp mknrc ; make NRC set
- atdgnrx:ret ; ignore
- atdgnrc endp
-
- ; Find NRC country number, putting it into CX, given Final char in AL and
- ; intermediates in array inter. Return carry set if not found.
- findctry proc near
- cmp ninter,2 ; second intermediate (%)?
- jb findct1 ; b = no
- ja findct3 ; a = three or more, no match
- mov ah,inter+1 ; get NRC intermediate
- cmp ax,'%6' ; Portugese NRC?
- jne findct4 ; ne = no, try Hebrew
- mov cx,9 ; Portuguese NRC is number 9
- clc
- ret
- findct4:cmp ax,'%=' ; Hebrew NRC?
- jne findct3 ; ne = no, fail
- mov cx,13 ; Hebrew NRC is number 13
- clc
- ret
- findct1:cmp ninter,0 ; no intermediate?
- je findct3 ; e = yes, no designator, fail
- mov cx,nrcflen ; number of NRC letters to consider
- cld
- push di ; save regs
- push es
- push ds
- pop es
- mov di,offset nrcfinal ; list of NRC final chars
- repne scasb ; look for a match
- pop es ; recover reg
- jne findct2 ; ne = failed
- dec di ; compenstate for auto-inc
- sub di,offset nrcfinal ; get distance covered
- mov cl,nrcnum[di] ; country number from parallel list
- xor ch,ch ; return number in CX
- pop di
- clc ; success
- ret
- findct2:pop di ; carry set = failure
- findct3:stc
- ret
- findctry endp
-
- ; Worker for atdgf routines. Return setptr looking at Gnset (n=0..3) and
- ; carry clear, based on ninter=1, inter = Gn designator. Carry set if fail.
- ; Modifies AL
- atdgset proc near
- cmp ninter,1 ; one intermediate?
- jne atdgsex ; ne = no, ignore
- mov al,inter ; inter, from parser
- cmp al,'(' ; 94 char sets, designate G0?
- je atdgse0 ; e = yes
- cmp al,')' ; G1?
- je atdgse1
- cmp al,'*' ; G2?
- je atdgse2
- cmp al,'+' ; G3?
- je atdgse3
- cmp al,'-' ; 96 char sets, designate G1?
- je atdgse1
- cmp al,'.' ; G2?
- je atdgse2
- cmp al,'/' ; G3?
- je atdgse3
- atdgsex:stc ; carry set for failure
- ret
- atdgse0:mov setptr,offset G0set ; designate G0 set
- clc
- ret
- atdgse1:mov setptr,offset G1set ; designate G1 set
- clc
- ret
- atdgse2:mov setptr,offset G2set ; designate G2 set
- clc
- ret
- atdgse3:mov setptr,offset G3set ; designate G3 set
- clc
- ret
- atdgset endp
- ; S7C1T/S8C1T select 7/8-bit controls
- ats7c: test flags.vtflg,ttvt320+ttvt220 ; in VT320/VT220 mode?
- jz atdgsex ; z = no, ignore command
- cmp ninter,1 ; one intermediate?
- jne ats7ca ; ne = no
- cmp inter,' ' ; proper intermediate?
- jne ats7ca ; ne = no
- and vtemu.vtflgop,not vscntl ; turn off 8-bit controls bit
- ats7ca:ret ; done
-
- ats8c: cmp inter,' ' ; proper intermediate?
- jne ats8ca ; ne = no
- cmp ninter,1 ; just one?
- jne ats8ca ; ne = no
- or vtemu.vtflgop,vscntl ; turn on 8-bit controls bit
- ats8ca: ret
-
- ; Designate User Preferred Supplemental Set as
- ; 'A' ISO Latin-1 or '%','5' DEC Supplemental Graphics, or
- ; 'H' Hebrew-ISO, or '"','4' DEC-Hebrew
- ; Store the selection letters in array upss for later use by ESC <char> '<'
- atupss: cmp word ptr dinter,0+'!' ; "!u" proper intermediate?
- je atupss0 ; e = yes
- mov ninter,0 ; set up atdcsnul for proper form
- jmp atdcsnul ; consume unknown command
- atupss0:mov ah,94 ; assume 94 byte set
- cmp dparam,1 ; 96 byte char size indicator?
- jb atupss1 ; b = no, 94
- ja atupss2 ; a = illegal Parameter
- mov ah,96 ; say 96
- atupss1:mov upss,ah ; store char set size
- mov ttstateST,offset atupss4; where to go when ST has been seen
- mov emubufc,0 ; clear buffer count
- mov ttstate,offset atupss2 ; next state is get string
- ret
- atupss2:mov bx,emubufc ; count of chars in string buffer
- cmp bx,emubufl ; too many?
- jae atupss3 ; ae = too many, ignore extras
- mov emubuf[bx],al ; store the char
- inc emubufc ; count it
- atupss3:ret
- atupss4:mov si,emubufc ; count of chars in string
- mov emubuf[si],0 ; terminate string in null
- mov ax,word ptr emubuf ; copy two chars from string to
- mov word ptr upss+1,ax ; upss char set ident storage area
- mov emubufc,0 ; clear the string count
- ret
-
- ; Select/map character sets
- atls0: mov GLptr,offset G0set ; LS0, map G0 char set into GLeft
- ret ; Control-O
- atls1: mov GLptr,offset G1set ; LS1, map G1 char set into GLeft
- ret ; Control-N
- atls1r: cmp ninter,0 ; any intermediate chars?
- jne atlsx ; ne = yes, not a Locking Shift
- mov GRptr,offset G1set ; LS1R, map G1 char set into GRight
- ret
- atss2: cmp ninter,0 ; any intermediate chars?
- jne atlsx ; ne = yes, not a Single Shift
- mov SSptr,offset G2set ; SS2, use G2 for next graphics only
- ret
- atls2: cmp ninter,0 ; any intermediate chars?
- jne atlsx ; ne = yes, not a Locking Shift
- mov GLptr,offset G2set ; LS2, map G2 char set into GLeft
- ret
- atls2r: cmp ninter,0 ; any intermediate chars?
- jne atlsx ; ne = yes, not a Locking Shift
- mov GRptr,offset G2set ; LS2R, map G2 char set into GRight
- ret
- atss3: cmp ninter,0 ; any intermediate chars?
- jne atlsx ; ne = yes, not a Single Shift
- mov SSptr,offset G3set ; SS3, use G3 for next graphics only
- ret
- atls3: cmp ninter,0 ; any intermediate chars?
- jne atlsx ; ne = yes, not a Locking Shift
- mov GLptr,offset G3set ; LS3, map G3 char set into GLeft
- ret
- atls3r: cmp ninter,0 ; any intermediate chars?
- jne atlsx ; ne = yes, not a Locking Shift
- mov GRptr,offset G3set ; LS3R, map G3 char set into GRight
- atlsx: ret
-
-
- ; Routine to set default character set.
- chrdef proc near
- mov GLptr,offset G0set ; map G0 set to GLeft
- mov GRptr,offset G2set ; map G2 set to GRight
- mov SSptr,0 ; clear single shift
- mov bx,offset emubuf ; temp table of char set idents
- mov word ptr [bx],0 ; G0 and G1 to ASCII
- mov al,vtemu.vtchset ; user specifed char set for GL
- mov byte ptr [bx+2],al ; set G2 and G3 to user selected set
- mov byte ptr [bx+3],al
- test flags.vtflg,ttvt320+ttvt220
- jnz chrdef1 ; nz = yes, 8-bit terminals
- mov GRptr,offset G1set ; map G1 set to GRight
- mov byte ptr [bx+1],18 ; assume Dec Special Graphics in G1
-
- chrdef1:test vtemu.vtflgop,vsnrcm ; doing National Replacement Chars?
- jz chrdef2 ; z = no
- mov al,vtemu.vtchset ; get country number
- mov dgkbl,al ; keyboard language
- cmp al,13 ; max NRC country
- ja chrdef2 ; a = out of bounds, ignore
- and vtemu.vtflgop,not vscntl ; turn off 8-bit controls
- mov ah,al ; country number 1..12
- mov [bx],al ; set G0
- test flags.vtflg,ttd463+ttd470 ; D463/D470?
- jnz chrdef2 ; nz = yes, don't touch G1..G3 here
- mov [bx+1],ah
- mov word ptr [bx],ax ; same char set in G0..G3
- mov word ptr [bx+2],ax
-
- chrdef2:test flags.vtflg,ttd463+ttd470 ; D463/D470?
- jz chrdef5 ; z = no (should have all cases now)
- mov al,20 ; D463/D470 DG International to G1
- test flags.remflg,d8bit ; 8 bit mode?
- jnz chrdef4 ; nz = yes
- chrdef3:mov al,22 ; D463/D470 DG Word Processing to G1
- chrdef4:mov [bx+1],al ; D463/D470 G1 default
- mov dgkbl,al ; DG keyboard language
- mov ah,[bx] ; G0
- or ah,ah ; using NRCs?
- jz chrdef5 ; z = no
- mov dgkbl,ah ; yes, state NRC in use for kbd
-
- chrdef5:call chrsetup ; worker to setup G0..G3
- ; do table of Gn overrides
- mov bx,offset vtemu.vttable ; table of char set overrides
- call chrsetup ; worker to setup G0..G3
- ret
- chrdef endp
-
- ; Load G0..G3 with character sets whose idents (0..24) are in byte array
- ; pointed to by BX. Update Gsetid with those byte idents enroute.
- chrsetup proc near
- push ninter ; preserve these
- mov ch,inter
- push cx ; save them
- mov ninter,1 ; one intermediate
- mov inter,'(' ; init inter for atdgset
- xor cx,cx ; count sets from 0
- chrset1:push cx ; save loop counter
- push bx
- call atdgset ; get setptr = offset Gnset (n=0..3)
- mov al,[bx] ; get char set ident from 4 byte list
- cmp al,0ffh ; none?
- je chrset90 ; e = none
- mov bx,cx ; update Gsetid table with set ident
- mov Gsetid[bx],al
- or al,al ; ASCII (0)?
- jnz chrset13 ; nz = no
- call mkascii ; make ASCII
- jmp chrset90
-
- chrset13:cmp al,13 ; in NRC's?
- ja chrset14 ; a = no
- mov cl,al ; put country number in cx
- xor ch,ch
- call mknrc ; setup an NRC, using cx and setptr
- jmp short chrset90
-
- chrset14:cmp al,14 ; want ALT-ROM?
- jne chrset15 ; ne = no
- call mkaltrom ; do ALT-ROM setup
- jmp short chrset90
-
- chrset15:cmp al,15 ; Transparent (15)?
- jne chrset16 ; ne = no
- call mkxparent ; do Transparent setup
- jmp short chrset90
-
- chrset16:cmp al,16 ; Latin1 (16)?
- jne chrset17
- cmp setptr,offset G0set ; want 96 byte set in G0?
- je chrset90 ; e = yes, can not do this
- call mklatin1 ; make Latin1
- jmp short chrset90
-
- chrset17:cmp al,17 ; DEC-MCS (17)?
- jne chrset18 ; ne = no
- call mkdecmn ; make DEC Supplement Graph (DEC-MCS)
- jmp short chrset90
-
- chrset18:cmp al,18 ; DEC-Technical (18)?
- jne chrset19 ; ne = no
- call mkdectech ; make DEC Technical
- jmp short chrset90
-
- chrset19:cmp al,19 ; DEC-Special-Graphics?
- jne chrset20 ; ne = no
- call mkdecspec ; make DEC Special Graphics
- jmp short chrset90
-
- chrset20:cmp al,20 ; DG International?
- jne chrset21 ; ne = no
- call mkdgint ; make DG International
- jmp short chrset90
-
- chrset21:cmp al,21 ; DG Line Drawing?
- jne chrset22 ; ne = no
- call mkdgld ; make DG line drawing
- jmp short chrset90
-
- chrset22:cmp al,22 ; DG Word Processing?
- jne chrset23 ; ne = no
- call mkdgwp ; make DG Word Procssing
- jmp short chrset90
-
- chrset23:cmp al,23 ; Latin1/CP852?
- jne chrset24 ; ne = no
- call mklatin2
- jmp short chrset90
-
- chrset24:cmp al,24 ; Hebrew-ISO (CP862)?
- jne chrset100 ; ne = no
- call mklatin_hebrew
- jmp short chrset90
-
- chrset100:cmp al,100 ; possible DG soft set?
- jne chrset90 ; ne = no
- test flags.vtflg,ttd463+ttd470 ; D463/D470?
- jz chrset90 ; z = no
- call mkdgtr ; do it
-
- chrset90:pop bx
- pop cx
- inc bx ; next byte of table
- inc inter ; next set pointer
- inc cx
- cmp cx,4 ; done all sets?
- jae chrset92 ; ae = yes
- jmp chrset1 ; b = no (counting sets as 0..3)
- chrset92:pop cx ; recover saved parsing items
- mov inter,cl ; restore
- pop ninter ; this too
- ret
- chrsetup endp
-
- ; copy gsize+3 bytes from (si) to (setptr)
- cpyset proc near
- push di
- push es
- push ds
- pop es
- cld
- mov cx,gsize+3 ; gsize chars plus three ident bytes
- mov di,setptr ; destination
- rep movsb
- pop es
- pop di
- ret
- cpyset endp
-
- ; Make Data General International to Gn table.
- ; Enter with destination in setptr
- mkdgint proc near
- push si
- push di
- call flatin1 ; get BX to Code Page dependent Latin1
- call cpyset ; copy in Latin1
- mov di,setptr
- mov al,[di+gsize+3] ; get Gn number (0..3)
- xor ah,ah
- mov si,ax
- mov Gsetid[si],20 ; store our char set ident
- add di,20h ; where new chars start
- mov si,offset dgi2lat ; source = code points in Latin1
- mov cx,dgi2len ; number of new chars
- push es
- push ds
- pop es
- cld
- mkdgin1:lodsb ; read Latin1 code point from dgi2lat
- cmp al,80h ; "?" unknown indicator or ASCII?
- jb mkdgin2 ; b = yes, reproduce it literally
- sub al,80h ; map down to indexable value
- xlatb ; translate through Latin1 table
- mkdgin2:stosb ; store in active table
- loop mkdgin1 ; do all necessary
- mov di,setptr
- mov byte ptr[di+gsize],94 ; say this is a 94 byte set
- mov word ptr[di+gsize+1],'ID' ; set ident code
- pop es
- pop di
- pop si
- ret
- mkdgint endp
-
- ; Make Data General line drawing graphics to Gn table.
- ; Enter with destination in setptr
- mkdgld proc near
- push si
- push di
- mov di,setptr
- mov al,[di+gsize+3] ; get Gn number (0..3)
- xor ah,ah
- mov si,ax
- mov Gsetid[si],21 ; store our char set ident
- mov cx,gsize ; first fill with spaces
- mov al,20h
- push es
- push ds
- pop es
- push di ; save starting location
- cld
- rep stosb ; spaces
- pop di
- add di,20h ; where new chars start
- mov si,offset dgldc ; replacement chars
- mov cx,dgldclen ; number of new chars
- rep movsb ; copy them to the table
- mov di,setptr
- mov byte ptr[di+gsize],94 ; say this is a 94 byte set
- mov word ptr[di+gsize+1],'LD' ; set ident code
- pop es
- pop di
- pop si
- ret
- mkdgld endp
-
- ; Make Data General word processing to Gn table.
- ; Enter with destination in setptr
- mkdgwp proc near
- push si
- push di
- mov di,setptr
- mov al,[di+gsize+3] ; get Gn number (0..3)
- xor ah,ah
- mov si,ax
- mov Gsetid[si],22 ; store our char set ident
- mov cx,gsize ; first fill with spaces
- mov al,20h
- push es
- push ds
- pop es
- push di ; save starting location
- cld
- rep stosb ; spaces
- pop di
- add di,20h ; where new chars start
- mov si,offset dgwpcp437 ; replacement chars
- mov cx,dgwplen ; number of new chars
- rep movsb ; copy them to the table
- mov di,setptr
- mov byte ptr[di+gsize],94 ; say this is a 94 byte set
- mov word ptr[di+gsize+1],'WD' ; set ident code
- pop es
- pop di
- pop si
- ret
- mkdgwp endp
-
- ; Make Data General soft set filler to Gn table.
- ; Enter with destination in setptr
- mkdgtr proc near
- push si
- push di
- mov di,setptr
- mov al,[di+gsize+3] ; get Gn number (0..3)
- xor ah,ah
- mov si,ax
- mov Gsetid[si],100 ; store our char set ident
- mov cx,gsize ; fill with "?"
- mov al,'?'
- push es
- push ds
- pop es
- cld
- rep stosb ; fill with "?"
- mov di,setptr
- mov byte ptr[di+gsize],94 ; say this is a 94 byte set
- mov word ptr[di+gsize+1],'UD' ; set ident code
- pop es
- pop di
- pop si
- ret
- mkdgtr endp
-
- ; Make DEC Alt-ROM to Gn table.
- ; Enter with destination in setptr
- mkaltrom proc near
- call mkascii ; init set to ASCII
- push si
- push di
- push es
- push ds
- pop es ; point es at data segment
- mov di,setptr
- mov al,[di+gsize+3] ; get Gn number (0..3)
- xor ah,ah
- mov si,ax
- mov Gsetid[si],14 ; store our char set ident
- add di,60h ; replace a..z with 20h + (a..z)
- mov si,di ; special graphics table
- mov cx,27 ; number of chars to do (a..z)
- cld
- decalt1:lodsb ; get a char
- add al,20h ; map up by 20h
- stosb
- loop decalt1
- mov di,setptr
- mov byte ptr[di+gsize],96 ; say this is a 96 byte set
- mov word ptr[di+gsize+1],0+'1' ; set ident code
- pop es
- pop di
- pop si
- ret
- mkaltrom endp
-
- ; Make DEC special graphics to Gn table.
- ; Enter with destination in setptr
- mkdecspec proc near
- call mkascii ; init set to ASCII
- push si
- push di
- mov di,setptr
- mov al,[di+gsize+3] ; get Gn number (0..3)
- xor ah,ah
- mov si,ax
- mov Gsetid[si],19 ; store our char set ident
- add di,95 ; replace chars 95-126
- mov si,offset sgrtab ; use DEC special graphics table
- mov cx,sgrtabl ; table length
- test flags.vtflg,ttheath ; Heath rather than VT?
- jz mkdecsp1 ; z = no
- mov si,offset hgrtab ; use Heath table
- mov cx,hgrtabl
- dec di ; work from 94 rather than 95
- mkdecsp1:push es
- push ds
- pop es
- cld
- rep movsb ; replace chars with sgrtab items
- mov di,setptr
- mov byte ptr[di+gsize],94 ; say this is a 94 byte set
- mov word ptr[di+gsize+1],0+'0' ; set ident code
- pop es
- pop di
- pop si
- clc
- ret
- mkdecspec endp
-
- ; Make Dec Technical to Gn table
- ; Enter with destination in setptr
- mkdectech proc near
- push si
- push di
- mov di,setptr
- mov al,[di+gsize+3] ; get Gn number (0..3)
- xor ah,ah
- mov si,ax
- mov Gsetid[si],18 ; store our char set ident
- mov si,offset dectech ; source data
- call cpyset ; copy the set to setptr's place
- mov di,setptr
- mov byte ptr[di+gsize],94 ; say this is a 96 byte set
- mov word ptr[di+gsize+1],0+'>' ; set ident code
- pop di
- pop si
- clc
- ret
- mkdectech endp
-
- ; Make Heath-19 special graphics to Gn table. Enter with dest of setptr.
-
- ; Initialize a char set to ASCII values 0..127 and ident of 94/B
- ; Enter with setptr holding offset of G0set, G1set, G2set, or G3set char set
- mkascii proc near
- push ax
- push cx
- push di
- push es
- mov di,setptr ; char set to init (G0..G3)
- mov al,[di+gsize+3] ; get Gn number (0..3)
- xor ah,ah
- mov si,ax
- mov Gsetid[si],0 ; store our char set ident
- mov cx,gsize ; number of bytes to do
- xor al,al ; initial value
- push ds
- pop es ; set es to data segment
- cld
- mkascii1:stosb ; copy value to char set table
- inc al
- loop mkascii1
- mov di,setptr
- mov byte ptr[di+gsize],94 ; say this is a 94 byte set
- mov word ptr[di+gsize+1],0+'B' ; set ident code to ASCII "B"
- pop es
- pop di
- pop cx
- pop ax
- ret
- mkascii endp
-
- ; Make UK ASCII to table Gn
- ; Enter with destination in setptr
- mkukascii proc near
- call mkascii ; make US ASCII table
- push di
- mov di,setptr ; get set pointer
- mov al,[di+gsize+3] ; get Gn number (0..3)
- xor ah,ah
- mov si,ax
- mov Gsetid[si],1 ; store our char set ident
- mov byte ptr[di+23h],156 ; replace sharp 2/3 with Sterling sign
- mov byte ptr[di+gsize],94 ; say this is a 94 byte set
- mov word ptr[di+gsize+1],0+'A' ; set ident code
- pop di
- ret
- mkukascii endp
-
- ; Make DEC Multinational Char Set (DEC-MCS/DEC Supplemental Graphics)
- ; and put into Gn table indicated by AL = 0..3
- ; Enter with destination in setptr
- mkdecmn proc near
- push si
- push di
- mov al,[di+gsize+3] ; get Gn number (0..3)
- xor ah,ah
- mov si,ax
- mov Gsetid[si],17 ; store our char set ident
- call flatin1 ; get Latin1 to BX
- mov si,bx
- call cpyset ; copy the set, gsize+3 bytes
- mov si,offset MNlatin ; get update table
- mov di,setptr
- mov cx,16 ; number of updates
- xor bh,bh
- mkdecmn1:mov bl,[si] ; get Latin1 code point to be changed
- and bl,not 80h ; map down to 0..127 range
- mov al,[si+16] ; get new value
- mov [di+bx],al ; store new value
- inc si
- loop mkdecmn1
- mov di,setptr
- mov byte ptr[di+gsize],96 ; say this is a 96 byte set
- mov word ptr[di+gsize+1],'5%' ; set ident code
- pop di
- pop si
- ret
- mkdecmn endp
-
- ; Put transparent char set (128..255) into Gn table.
- ; Enter with destination in setptr
- mkxparent proc near
- call mkascii ; init set to ASCII
- push si
- push di
- mov di,setptr ; point at character set
- mov al,[di+gsize+3] ; get Gn number (0..3)
- xor ah,ah
- mov si,ax
- mov Gsetid[si],1 ; store our char set ident
- mov cx,gsize ; number of chars to do, 128
- cld
- mov al,cl ; start with 128 char value
- push es
- push ds
- pop es ; point es at data segment
- mkxpar2:stosb ; store codes 128..255
- inc al
- loop mkxpar2
- mov di,setptr
- mov byte ptr[di+gsize],96 ; say this is a 96 byte set
- mov word ptr[di+gsize+1],0+'?' ; set ident code
- pop es
- pop di
- pop si
- ret
- mkxparent endp
-
- ; Construct NRC table.
- ; Enter with destination in setptr
- ; and CX holding the desired country code (1..13).
- mknrc proc near
- call mkascii ; init set to ASCII
- push bx
- push cx
- push si
- push di
- push word ptr emubuf
- push word ptr emubuf+2
- push es
- mov di,setptr
- mov al,[di+gsize+3] ; get Gn number (0..3)
- xor ah,ah
- mov si,ax
- mov Gsetid[si],cl ; store our char set ident
- mov emubuf+2,cl ; local copy
- cmp cl,13 ; DEC Hebrew case?
- je mknrc10 ; e = yes
- ; copy from NRC table (si) to set pointed at by di, cx chars
- ; plus 3 ident bytes at table end
- mov word ptr emubuf,offset nrclat ; start of NRC to Latin1 table
- mov ax,cx ; country code 1..12
- mov bl,15 ; 15 bytes per entry
- mul bl ; distance down the table to country
- add word ptr emubuf,ax ; point at country line
- mov cx,12 ; do 12 bytes of new chars
- push ds
- pop es
- cld
- call flatin1 ; returns BX = Latin1 to CPnnn table
- xor si,si
- mknrc2: mov al,nrclat[si] ; get code point to change
- xor ah,ah
- mov di,setptr ; start of destination table
- add di,ax ; destination of new char
- push bx
- mov bx,word ptr emubuf ; ptr to country entries
- mov al,[bx+si] ; read char from NRC table
- pop bx
- inc si
- test al,80h ; in GR Latin1 area?
- jz mknrc3 ; z = no, in ASCII GL area
- and al,not 80h ; trim high bit for xlat
- xlatb ; translate through Latin1 Code Page
- mknrc3: stosb ; move replacement char from nrc list
- loop mknrc2
-
- mov di,setptr
- test flags.vtflg,ttd463+ttd470 ; D463/D470?
- jz mknrc8 ; z = no
- mov cl,emubuf+2 ; country code again
- cmp cl,3 ; French NRC?
- jne mknrc4 ; ne = no
- mov al,07fh ; apply DG French NRC patch
- jmp short mknrc7
- mknrc4: cmp cl,6 ; Spanish NRC?
- jne mknrc5 ; ne = no
- mov al,07fh ; apply DG Spanish NRC patch
- jmp short mknrc7
- mknrc5: cmp cl,7 ; DG Danish/Norweigen NRC?
- jne mknrc6 ; ne = no
- mov al,0fch ; apply DG Danish/Norweigen NRC patch
- jmp short mknrc7
- mknrc6: cmp cl,8 ; Swiss NRC?
- jne mknrc7 ; ne = no
- mov al,0e9h ; apply DG Swiss NRC patch
- mknrc7: and al,not 80h
- xlatb ; push through Latin1 translation
- mov [di+7fh],al ; new value
- mknrc8: add di,gsize ; look at end of set, to id bytes
- movsb ; copy set size and two ident chars
- movsw
- jmp short mknrc11
-
- mknrc10:mov vtcpage,862 ; Hebrew NRC CP862
- call flatin1 ; get SI appropriate for Code Page
- mov si,bx ; point to Latin 1 for this code page
- add si,6*16 ; get Hebrew part of CP862
- mov di,ds
- mov es,di
- mov di,setptr
- add di,6*16
- mov cx,27 ; number of characters
- cld
- rep movsb
- mknrc11:pop es
- pop word ptr emubuf+2
- pop word ptr emubuf
- pop di
- pop si
- pop cx
- pop bx
- ret
- mknrc endp
-
- ; Construct Latin1 table to Gn table.
- ; Enter with destination in setptr
- mklatin1 proc near
- push si
- push di
- mov di,setptr ; destination
- mov al,[di+gsize+3] ; get Gn number (0..3)
- xor ah,ah
- mov si,ax
- mov Gsetid[si],16 ; store our char set ident
- call flatin1 ; get BX appropriate for Code Page
- mov si,bx
- mov cx,gsize ; bytes
- push es
- push ds
- pop es
- cld
- rep movsb ; copy bytes
- mov di,setptr
- mov byte ptr[di+gsize],96 ; say this is a 96 byte set
- mov word ptr[di+gsize+1],0+'A' ; set ident code
- pop es
- pop di
- pop si
- ret
- mklatin1 endp
-
- ; Construct Latin2 table to Gn table.
- ; Enter with destination in setptr
- mklatin2 proc near
- push si
- push di
- mov di,setptr ; destination
- mov al,[di+gsize+3] ; get Gn number (0..3)
- xor ah,ah
- mov si,ax
- mov Gsetid[si],16 ; store our char set ident
- mov vtcpage,852 ; set emulator's CP to CP852
- call flatin1 ; get BX appropriate for Code Page
- mov si,bx
- mov cx,gsize ; bytes
- push es
- push ds
- pop es
- cld
- rep movsb ; copy bytes
- mov di,setptr
- mov byte ptr[di+gsize],96 ; say this is a 96 byte set
- mov word ptr[di+gsize+1],0+'B' ; set ident code
- pop es
- pop di
- pop si
- ret
- mklatin2 endp
-
- ; Make DEC Hebrew (94) 8-bit Supplemental
- ; Same code points as Hebrew-ISO at this time
- mkdec_Hebrew proc near
- call mklatin_hebrew
- push es
- push ds
- pop es
- mov di,setptr
- mov byte ptr[di+gsize],94 ; say this is a 94 byte set
- mov word ptr[di+gsize+1],'4"' ; set ident code
- pop es
- ret
- mkdec_Hebrew endp
-
- ; Make Hebrew-ISO (96) 8-bit Supplemental to Gn pointer
- ; Enter with destination in setptr
- ; Presumes CP 862 is loaded
- mklatin_Hebrew proc near
- push si
- push di
- mov di,setptr ; destination
- mov al,[di+gsize+3] ; get Gn number (0..3)
- xor ah,ah
- mov si,ax
- mov Gsetid[si],24 ; store our char set ident
- mov cx,gsize ; bytes
- mov vtcpage,862 ; set emulator's CP to CP862
- call flatin1 ; get BX appropriate for Code Page
- mov si,bx
- push es
- push ds
- pop es
- cld
- rep movsb ; copy bytes
- mov di,setptr
- mov byte ptr[di+gsize],96 ; say this is a 96 byte set
- mov word ptr[di+gsize+1],0+'H' ; set ident code
- pop es
- pop di
- pop si
- ret
- mklatin_Hebrew endp
-
- ; Get output byte in AL from keyboard raw reader and convert through active
- ; Code Page translations. Return final output byte in AL
- ; Return modified char code, depending on SET TERM CHAR-SET and active
- ; Code Page. Enter and exit with char in AL.
- xltkey proc FAR
- cmp al,80h ; regular ASCII key?
- jb xltkey1 ; b = yes, do not translate
- cmp flags.xltkbd,0 ; keyboard translation is off?
- jne xltkey2 ; ne = no
- xltkey1:ret
-
- xltkey2:push es
- push ds
- pop es
- push di
- mov di,GRptr ; high bit is where GR points
- mov cx,gsize
- add di,cx
- std
- repne scasb ; scan looking for this code
- cld
- jne xltkey3 ; ne = not found
- inc di ; backup to found code
- sub di,GRptr ; minus start
- or di,80h ; put back high bit
- mov ax,di ; AL is the byte value
- xltkey3:pop di
- pop es
- ret
- xltkey endp
-
- ; cursor movements
-
- atcup: test dspstate,dsptype ; on VT320 status line?
- jz atcup0 ; z = no
- mov param,0 ; yes, do not change rows
- atcup0: mov dh,byte ptr param ; get row,col parameters
- mov dl,byte ptr param+2 ; dh is row, dl is column
- or dh,dh ; zero row number?
- jz atcup1 ; z = yes, continue
- dec dh ; normalize to 0,0 system
- atcup1: or dl,dl ; ditto for column
- jz atcup2
- dec dl
- atcup2: test vtemu.vtflgop,decom ; Origin mode?
- jz atcup3 ; z = no, skip this stuff
- add dh,mar_top ; yes, it was relative to top margin
- jno atcup3 ; if no overflow, continue
- mov dh,byte ptr low_rgt+1 ; otherwise just set to screen bottom
- atcup3: mov al,mar_right ; right margin
- cmp dl,al ; too far to the right?
- jbe atcup4 ; ne = no
- mov dl,al ; limit to right margin
- atcup4: mov ah,byte ptr low_rgt+1 ; last regular text line
- cmp dh,ah ; going to 25th line?
- jbe atcup7 ; be = no
- inc ah ; "25th" status line
- cmp flags.vtflg,ttheath ; emulating a Heath-19?
- je atcup5 ; e = yes
- cmp dh,ah ; going too far?
- je atcup8 ; e = no
- dec ah
- mov dh,ah ; last normal row
- atcup4a:jmp atsetcur ; set cursor here
-
- atcup5: cmp dh,ah ; going too far?
- ja atcup6 ; a = yes
- test h19stat,h19l25 ; Heath 25th mode line enabled?
- jnz atcup8 ; nz = yes
- atcup6: mov dh,byte ptr cursor+1 ; do not change rows
- atcup7: call atccpc ; check position
- atcup8: jmp atsetcur ; set cursor position and return
-
- atcuarg:mov al,byte ptr param ; worker, get cursor movement argument
- or al,al ; zero?
- jnz atcua1 ; nz = no
- inc al ; default to one
- atcua1: ret
- ; cursor up
- atcuu: cmp dh,byte ptr low_rgt+1 ; on 25th line?
- jbe atcuu1 ; be = no
- ret ; no vertical for Heath on 25th line
- atcuu1: call atcuarg ; get cursor move up argument into al
- sub dh,al ; compute new cursor position
- jnc atcuu2 ; nc = ok [dlk]
- xor dh,dh ; overflow, restrict range. [dlk]
- atcuu2: call atccic ; check indexing, ignore action in ax
- jmp atsetcur ; set the cursor at its new position
-
- atcud: call atcuarg ; cursor down
- cmp dh,byte ptr low_rgt+1 ; on 25th line now?
- jbe atcud1 ; be = no
- ret ; else leave it on status line
- atcud1: add dh,al ; compute new cursor position
- jnc atcud2 ; nc = ok [dlk]
- mov dh,byte ptr low_rgt+1 ; default bottom [dlk]
- atcud2: call atccic ; check indexing, ignore action in ax
- jmp atsetcur ; set the cursor at its new position
-
- ; Allow horiz movement on 25th line
- atcuf: call atcuarg ; cursor forward
- add dl,al ; compute new cursor position
- jnc atcup3 ; nc = no problem
- mov dl,byte ptr low_rgt ; else set to right margin
- jmp atcup3 ; check/set cursor, return
-
- atcub: call atcuarg ; cursor back
- sub dl,al ; compute new cursor position
- jnc atcub1 ; nc = no problem
- xor dl,dl ; else set to left margin
- atcub1: jmp atcup3 ; check/set cursor, return
-
- atcha: call atcuarg ; absolute horizontal address
- mov dl,al ; new column, counted from 1
- sub dl,1 ; column, count from 0 internally
- jns atcha1 ; ns = no problem
- xor dl,dl ; else set to left margin
- atcha1: jmp atcup3 ; check/set cursor, return
-
- atcht: call atcuarg ; move cursor forward # horiz tabs
- inc dl ; next column
- mov cl,al ; number of tabstops to locate
- xor ch,ch
- mov si,offset tabs ; active tabs buffer
- atcht1: cmp dl,mar_right ; at end of line?
- jae atcht2 ; ae = yes, stop here
- call istabs ; is dl column a tabstop?
- inc dl ; try next column, preserves carry
- jnc atcht1 ; nc = no, find one
- loop atcht1 ; do cx tabstops
- atcht2: jmp atcup3 ; set cursor
-
- atcva: inc dl ; count columns from 1 here
- mov byte ptr param+2,dl ; set column in second parameter
- mov param+3,0 ; high byte
- jmp atcup ; do absolute vertical positioning
-
- atcnl: call atcuarg ; do # Next-Lines
- cmp dh,byte ptr low_rgt+1 ; on 25th line now?
- jbe atcnl1 ; be = no
- ret ; else leave it on status line
- atcnl1: mov cl,al ; number to do
- xor ch,ch
- atcnl2: push cx
- inc dh ; number to do
- mov dl,mar_left
- call atccic ; check cursor position
- call ax ; scroll if necessary
- call atsetcur ; set cursor, etc. and return
- pop cx
- loop atcnl2
- ret
- atcpl: call atcuarg ; do # Previous-Lines
- cmp dh,byte ptr low_rgt+1 ; on 25th line now?
- jbe atcpl1 ; be = no
- ret ; else leave it on status line
- atcpl1: mov cl,al ; number to do
- xor ch,ch
- mov dl,mar_left
- atcpl2: dec dh ; do one line
- push cx ; save counter
- call atccic ; check cursor position
- call ax ; scroll if necessary
- call atsetcur ; set cursor
- pop cx
- loop atcpl2 ; do cx times
- ret
-
- ; Screen erasure commands
- ; Erase in display
- ated: cmp ninter,0 ; zero intermediates?
- je ated0 ; e = yes, else try protected mode
- ret
-
- ated0: cmp lparam,0
- je ated0a
- jmp atedsel
- ated0a: cmp param,0 ; was arg zero?
- jne ated1 ; ne = no
- jmp ereos ; do erase cursor to end of screen
-
- ated1: cmp param,1 ; was arg one?
- jne ated2 ; ne = no
- jmp ersos ; do erase start of screen to cursor
-
- ated2: cmp param,2 ; was arg two?
- je ated2a ; e = yes, erase entire screen
- ret ; else ignore
- ated2a: push dx ; save dynamic cursor
- push word ptr mar_top
- mov mar_bot,dh
- mov mar_top,0 ; row of cursor
- inc dh ; number of lines to scroll
- mov scroll,dh
- call atscru ; scroll them up before erasure
- pop word ptr mar_top
- pop dx
- call ersos ; erase start of screen to cursor
- call ereos ; erase cursor to end of screen
- ret
-
-
- atedsel proc near ; DECSED selective erase in display
- cmp lparam,'?' ; proper intermediate?
- jne atedsel3 ; ne = no
- mov ax,param ; get parameter
- or ax,ax ; 0?
- jnz atedsel1 ; nz = no
- mov al,mar_top ; 0: erase cursor to end of screen
- mov ah,mar_bot ; save margins
- push ax
- mov mar_top,dh ; use current row
- mov ah,byte ptr low_rgt+1 ; bottom screen row for text
- mov mar_bot,ah
- call erprot ; do protected mode erasure
- pop ax
- mov mar_top,al ; restore margins
- mov mar_bot,ah
- jmp short atedsel3
- atedsel1:cmp al,1 ; 1? erase start of line to cursor
- jne atedsel2 ; ne = no
- mov al,mar_top ; 1: erase start to cursor
- mov ah,mar_bot ; save margins
- push ax
- mov al,mar_right
- mov ah,dl ; save right margin and cursor col
- push ax
- mov mar_right,dl ; stop at current cursor
- mov dl,mar_left ; start at this pseudo cursor
- mov mar_top,dh ; use current row
- mov mar_bot,dh
- call erprot ; do protected mode erasure
- pop ax
- mov mar_right,al ; restore right margin
- mov dl,ah ; restore cursor row
- pop ax
- mov mar_top,al ; restore margins
- mov mar_bot,ah
- jmp short atedsel3
- atedsel2:cmp al,2 ; 2? erase whole line
- jne atedsel3 ; ne = no
- mov al,mar_top ; 2: erase whole screen
- mov ah,mar_bot ; save margins
- push ax
- mov ah,mar_right
- mov al,mar_left
- push ax
- push dx ; save cursor
- xor dx,dx ; set to top left corner
- mov mar_right,dl ; starting point
- mov mar_top,dh
- mov ax,low_rgt ; lower right corner of text area
- mov mar_left,al ; start at this pseudo cursor
- mov mar_bot,ah
- call erprot ; do protected mode erasure
- pop dx ; restore cursor
- pop ax
- mov mar_left,al
- mov mar_right,ah
- pop ax
- mov mar_top,al ; restore margins
- mov mar_bot,ah
- atedsel3:ret
- atedsel endp
-
-
- p20ed: xor dx,dx ; Prime PT200, set cursor to 0,0
- call ereos ; erase cursor to end of screen
- jmp atsetcur ; put cursor at 0,0 and return
-
- ; Erase in current line
- atel: cmp ninter,0 ; zero intermediates?
- je atel0 ; e = yes
- ret
-
- atel0: cmp lparam,0 ; letter parameter?
- je atel0a
- jmp atelsel ; try protected mode erasure
- atel0a: cmp param,0 ; was arg zero?
- jne atel1 ; ne = no
- mov al,dl ; erase from cursor
- mov bl,byte ptr low_rgt ; to end of line, inclusive
- jmp erinline ; do the erasure
-
- atel1: cmp param,1 ; was arg one?
- jne atel2 ; ne = no
- xor al,al ; erase from start of line
- mov bl,dl ; to cursor, inclusive
- jmp erinline ; do the erasure
-
- atel2: cmp param,2 ; was arg two?
- jne atel3 ; ne = no, ignore
- xor al,al ; erase entire line
- mov bl,byte ptr low_rgt
- jmp erinline ; clear it
- atel3: ret
-
-
- atelsel proc near ; DECSEL selective erase in line
- cmp lparam,'?' ; proper intermediate?
- jne atelsel3 ; ne = no
- mov ax,param ; get parameter
- or ax,ax ; 0?
- jnz atelsel1 ; nz = no
- mov al,mar_top ; 0: erase cursor to end of line
- mov ah,mar_bot ; save margins
- push ax
- mov mar_top,dh ; use current row
- mov mar_bot,dh
- call erprot ; do protected mode erasure
- pop ax
- mov mar_top,al ; restore margins
- mov mar_bot,ah
- ret
- atelsel1:cmp al,1 ; 1? erase start of line to cursor
- jne atelsel2 ; ne = no
- mov al,mar_top ; 1: erase start to cursor
- mov ah,mar_bot ; save margins
- push ax
- mov al,mar_right
- mov ah,dl ; save right margin and cursor col
- push ax
- mov mar_right,dl ; stop at current cursor
- mov dl,mar_left ; start at this pseudo cursor
- mov mar_top,dh ; use current row
- mov mar_bot,dh
- call erprot ; do protected mode erasure
- pop ax
- mov mar_right,al ; restore right margin
- mov dl,ah ; restore cursor row
- pop ax
- mov mar_top,al ; restore margins
- mov mar_bot,ah
- ret
- atelsel2:cmp al,2 ; 2? erase whole line
- jne atelsel3 ; ne = no
- mov al,mar_top ; 2: erase whole line
- mov ah,mar_bot ; save margins
- push ax
- mov ah,dl ; save right margin and cursor col
- push ax
- mov mar_right,dl ; stop at current cursor
- mov dl,mar_left ; start at this pseudo cursor
- mov mar_top,dh ; use current row
- mov mar_bot,dh
- call erprot ; do protected mode erasure
- pop ax
- mov dl,ah ; restore cursor row
- pop ax
- mov mar_top,al ; restore margins
- mov mar_bot,ah
- atelsel3:ret
- atelsel endp
-
- ; ECH, erase chars in this line
- atech: mov ax,dx ; get cursor position
- mov bx,ax ; erase ax to bx
- cmp byte ptr param,0 ; 0 argument
- je atech1 ; e = yes
- dec bl ; count from 1
- atech1: add bl,byte ptr param ; number of characters
- jmp erinline ; erase in this line
-
-
- ; Set Graphics Rendition commands (video attributes)
-
- atsgr: cmp lparam,0 ; any letter parameter?
- jne atsgr0 ; ne = yes, fail
- mov ah,curattr ; get current cursor attribute
- mov di,offset atsgr1 ; routine to call
- call atreps ; repeat for all parms
- mov curattr,ah ; store new attribute byte
- atsgr0: ret
-
- atsgr1: mov bx,param[si] ; fetch an argument
- or bl,bl ; 0, clear all attributes?
- jnz atsgr2 ; nz = no, do selectively below
- call clrbold ; clear bold attribute
- call clrblink ; clear blink attribute
- call clrrev ; clear reverse video attribute
- call clrunder ; clear underline attribute
- mov extattr,0 ; clear extended attributes
- ret
-
- atsgr2: cmp bl,1 ; 1, set bold?
- jne atsgr2a ; ne = no
- jmp setbold ; set bold attribute
-
- atsgr2a:cmp flags.vtflg,ttpt200 ; PT200 '2' = half intensity
- jne atsgr3 ; ne = no, do next attrib test
- cmp bl,2 ; PT200 - 2, set bold?
- jne atsgr3 ; ne = no
- jmp setbold ; set half intensity
-
- atsgr3: cmp bl,4 ; 4, set underline?
- jne atsgr4 ; ne = no
- jmp setunder ; set underline attribute
-
- atsgr4: cmp bl,5 ; 5, set blink?
- jne atsgr5 ; ne = no
- jmp setblink ; set blink attribute
-
- atsgr5: cmp bl,7 ; 7, reverse video for chars?
- jne atsgr6 ; ne = no, try coloring
- jmp setrev ; set reversed video attribute (AH)
-
- atsgr6: cmp flags.vtflg,ttheath ; Heath-19?
- jne atsgr9 ; ne = no
- cmp bl,10 ; 10, enter graphics mode?
- jne atsgr7 ; ne = no
- push ax ; save ah
- mov al,'F' ; simulate final char of 'F'
- call v52sgm ; do character setup like VT52
- pop ax
- ret
- atsgr7: cmp bl,11 ; 11, exit graphics mode?
- jne atsgr8 ; ne = no, ignore
- push ax ; save ah
- mov al,'G' ; simulate final char of 'G'
- call v52sgm ; do character setup like VT52
- pop ax
- atsgr8: ret
-
- atsgr9: test flags.vtflg,ttvt320+ttvt220 ; VT320/VT220?
- jz atsgr8 ; z = no, 22-27 are VT220/320 only
- cmp bl,22 ; 22, bold off?
- jne atsgr10 ; ne = no
- jmp clrbold
- atsgr10:cmp bl,24 ; 24, underline off?
- jne atsgr11 ; ne = no
- jmp clrunder
- atsgr11:cmp bl,25 ; 25, blinking off?
- jne atsgr12 ; ne = no
- jmp clrblink
- atsgr12:cmp bl,27 ; 27, reverse video off?
- jne atsgr13 ; ne = no
- jmp clrrev ; clear reversed video attribute (AH)
- atsgr13:jmp setcolor ; BL = color, AH = attribute byte
-
- ; Tabulation char commands
- attbc: call atccpc ; make sure cursor is kosher
- cmp ninter,0 ; zero intermediates?
- je attbc0 ; e = yes, else quit
- ret
- ; Tabstop set/clears
- attbc0: cmp param,0 ; was argument zero?
- jne attbc1 ; ne = no
- push si
- mov si,vtemu.vttbst ; active buffer
- call tabclr ; clear tabstop in column DL
- pop si
- ret
-
- attbc1: cmp param,3 ; was arg 3 (clear all tab stops)?
- je attbc2 ; e = yes
- ret ; else ignore
- attbc2: mov cx,(swidth+7)/8 ; get ready to zap swidth columns
- mov di,offset tabs ; point to the tab stop table
- xor al,al ; zero indicates no tab stop
- push es ; save es
- push ds
- pop es ; use data segment for es:di below
- cld ; set direction forward
- rep stosb ; clear all bits
- pop es
- ret
- ; set scrolling margins
- atstbm: test dspstate,dsptype ; on status line?
- jnz atstb3 ; nz = yes, ignore this command
- mov al,byte ptr param ; get the two line number args
- mov ah,byte ptr param+2
- or al,al ; was first zero?
- jnz atstb1 ; nz = no, continue
- inc al ; default is one
- atstb1: or ah,ah ; was second zero?
- jnz atstb2 ; nz = no
- mov ah,byte ptr low_rgt+1 ; yes, default is last line on screen
- inc ah
- atstb2: dec al ; normalize to 0,0 coordinate system
- dec ah
- cmp ah,al ; size of region at least two lines?
- jbe atstb3 ; be = no, indicate an error
- or al,al ; check against screen limits
- jl atstb3 ; l = out of range
- cmp ah,byte ptr low_rgt+1
- ja atstb3 ; a = too far down
- mov mar_top,al ; set the limits
- mov mar_bot,ah
- xor dx,dx ; Home cursor
- call atccpc
- jmp atsetcur ; set cursor position and return
- atstb3: ret ; ignore bad requests
-
- ; Device attributes commands
- atda: cmp param,0 ; was argument zero?
- je decid ; e = send the i.d. string
- ret ; no, only an echo
- decid: cmp ninter,0 ; any intermediates?
- je decid1 ; e = no, else not this item
- jmp atdgnrc ; try Spanish NRC designator
- decid1: mov ax,flags.vtflg ; get terminal ident type
- mov cx,30 ; assumed length of asciiz string
- mov si,offset v32str ; VT320 ident string
- cmp ax,ttvt320 ; VT320?
- je decid2 ; e = yes
- mov si,offset v22str
- cmp ax,ttvt220 ; VT220?
- je decid2 ; e = yes
- mov si,offset v102str
- cmp ax,ttvt102 ; VT102?
- je decid2 ; e = yes
- mov si,offset v100str
- cmp ax,ttvt100 ; VT100?
- je decid2 ; e = yes
- cmp ax,tthoney ; Honeywell?
- je decid2 ; e = yes
- mov si,offset v52str
- cmp ax,ttvt52 ; VT52?
- je decid2 ; e = yes
- mov si,offset h19str
- cmp ax,ttheath ; Heath-19 mode?
- je decid2 ; e = yes
- mov si,offset pt20str ; Prime PT200 string
- decid2: cmp lparam,'>' ; this letter parameter?
- jne decid3 ; ne = no
- test al,ttvt320+ttvt220 ; VT320/VT220 mode?
- jz decid4 ; z = no, ignore
- mov si,offset v32sda ; Secondary DA response string
- decid3: cld
- lodsb ; read string
- or al,al ; end of string?
- jz decid4 ; z = yes
- push cx
- push si
- call prtbout ; send it to port with no local echo
- pop si
- pop cx
- loop decid3 ; do all characters
- decid4: ret
- ; Display LED's
- atll: mov di,offset atleds ; get pointer to routine to call
- call atreps ; repeat for selective parameters
- ret
-
- atleds: push si ; set LED indicators
- call getled ; set si to term type (led) string
- mov di,si
- pop si
- jc atled2 ; c = no leds 1..4, ignore
- atled4: cmp param[si],0 ; zero argument?
- jne atled3 ; ne = no, check further
- mov al,led_off ; set all off
- mov ah,al
- mov [di+6],ax ; where dots go after name
- mov [di+6+2],ax
- atled1: test yflags,modoff ; mode line supposed to be off?
- jnz atled2 ; nz = yes
- push dx
- call fmodlin ; update status line
- pop dx
- atled2: ret
- atled3: mov ax,param[si] ; get the argument
- cmp al,1 ; must be 1 to 4
- jb atled2 ; b = out of range
- cmp al,4
- ja atled2 ; a = out of range
- dec ax ; zero base it
- push di
- add di,ax
- add al,'1' ; add ascii offset for digit
- mov [di+6],al ; turn the "LED" on by storing digit
- pop di
- jmp short atled1 ; update display and return
-
- decsca proc near ; DEC Select Character Attributes
- cmp ninter,1 ; one intermediate?
- jne atll ; no, try led routine
- cmp inter,'"' ; CSI Pn " q ?
- jne decsca2 ; ne = no
- cmp param,1 ; 0, 2 mean protected mode goes off
- jne decsca1 ; ne = not 1, protected mode goes on
- call setprot ; start protecting
- ret
- decsca1:call clrprot ; end protecting
- decsca2:ret
- decsca endp
-
-
- ; Set/Reset mode commands
- ; ESC [ ? xxx h/l Set/Reset series
- atrm: mov modeset,0 ; say we are resetting modes
- mov di,offset atrsm ; Reset/Set modes
- call atreps ; repeat for all parms
- test vtemu.vtflgop,decanm ; did ansi mode get reset?
- jnz atrm1 ; nz = no, return
- cmp flags.vtflg,ttheath ; were we a Heath-19?
- je atrm0 ; e = yes, don't change terminal types
- cmp flags.vtflg,ttpt200 ; were we a PT200?
- je atrm0 ; e = yes, don't change terminal types
- mov flags.vtflg,ttvt52 ; say VT52 now
- atrm0: call chrdef ; set default char sets
- call atsc ; save cursor status
- test yflags,modoff ; mode line supposed to be off?
- jnz atrm1 ; nz = yes
- call fmodlin ; update mode line
- atrm1: ret
-
- atsm: mov modeset,1 ; say we are setting modes
- mov di,offset atrsm ; Reset/Set modes
- jmp atreps ; repeat for all parms
-
- atrsm: mov ax,param[si] ; pick up the argument
- cmp lparam,'?' ; DEC private mode? ESC [ ?
- je atrsm1 ; e = yes, do DEC specific things
- cmp lparam,'>' ; Heath-19 private mode? ESC [ >
- jne atrsma ; ne = no
- jmp htrsm1 ; do Heath specific things
- ; ANSI level
- atrsma: cmp al,20 ; 20, ANSI new-line mode?
- jne atrsm0 ; ne = no, try insert mode
- and vtemu.vtflgop,not vsnewline ; assume resetting
- cmp modeset,0 ; resetting?
- je atrsmb ; e = yes
- or vtemu.vtflgop,vsnewline ; setting
- atrsmb: mov ax,anslnm ; get the flag bit
- jmp atrsflg ; set or reset it
- atrsm0: cmp al,4 ; toggle insert mode?
- jne atrsmc ; ne = no
- mov al,modeset ; set/reset insert mode
- mov insmod,al ; store it
- ret
- atrsmc: cmp al,12 ; 12? Control local echo
- jne atrsmx ; ne = no
- cmp modeset,0 ; resetting mode (ESC [ 12 l)?
- jne atrsmc1 ; ne = no
- or yflags,lclecho ; (l) turn on local echoing
- jmp short atrsmc2
- atrsmc1:and yflags,not lclecho ; (h) turn off local echoing
- atrsmc2:test yflags,modoff ; is mode line off?
- jnz atrsmx ; nz = yes
- push dx ; save cursor position
- call fmodlin ; write mode line
- pop dx
- atrsmx: ret
- ; DEC specifics
- atrsm1: cmp al,1 ; cursor keys mode?
- jne atrsm2 ; ne = no
- mov ax,decckm ; get the bit
- jmp atrsflg ; set or reset it and return
-
- atrsm2: cmp al,7 ; Auto-wrap?
- jne atrsm3 ; ne = no
- and vtemu.vtflgop,not vswrap ; assume resetting line wrap
- cmp modeset,0 ; resetting?
- je atrsm2a ; e = yes
- or vtemu.vtflgop,vswrap ; set the bit
- atrsm2a:mov ax,decawm ; get the bit
- jmp atrsflg ; set or reset it and return
-
- atrsm3: cmp al,6 ; Origin mode?
- jne atrsm4 ; ne = no
- jmp atrsom ; change decom and return
-
- atrsm4: cmp al,5 ; change the video?
- jne atrsm5 ; ne = no
- jmp atrsscnm ; yes, change it if necessary
-
- atrsm5: cmp al,2 ; Change VT52 compatibility mode?
- jne atrsm6 ; ne = no
- test dspstate,dsptype ; on status line?
- jnz atrsm5b ; nz = yes, ignore switch
- cmp flags.vtflg,ttheath ; Heath-19 mode?
- jne atrsm5a ; ne = no
- mov modeset,0 ; Heath ESC [ ? 2 h resets ANSI mode
- atrsm5a:mov ax,decanm ; get ansi mode flag
- call atrsflg ; set or reset it
- test yflags,modoff ; mode line supposed to be off?
- jnz atrsm5b ; nz = yes
- push dx ; save cursor position
- call fmodlin ; write mode line
- pop dx
- atrsm5b:ret
-
- atrsm6: cmp al,3 ; 132/80 column mode change?
- jne atrsm7 ; ne = no
- mov al,curattr ; save current video attributes
- mov ah,extattr ; and extended attributes
- push ax
- xor ah,ah ; high byte: not exiting Connect mode
- and vtemu.vtflgop,not deccol; assume mode is reset
- mov al,modeset ; pass set/reset request to chgdsp
- or al,al
- jz atrsm6a ; z = set 80 columns
- or vtemu.vtflgop,deccol ; assume it will work (tell msy)
- atrsm6a:call chgdsp ; call Change Display proc in msy
- and vtemu.vtflgop,not deccol; assume mode is reset
- cmp modeset,0 ; want 80 cols?
- je atrsm6n ; e = yes, else 132 cols
- cmp byte ptr low_rgt,79
- jbe atrsm6b
- or vtemu.vtflgop,deccol ; set the status bit
- mov byte ptr low_rgt,132-1 ; screen capability
- jmp short atrsm6e
- atrsm6b:and vtemu.vtflgst,not deccol; turn off setup 132 col bit too
- atrsm6n:cmp byte ptr low_rgt,79 ; want 80 cols, is it wider?
- jbe atrsm6e ; be = no
- mov byte ptr low_rgt,79 ; narrow down to 80 columns
- atrsm6e:test flags.vtflg,ttd463+ttd470 ; D463/D470?
- jnz atrsm6f ; nz = yes, no reset for DG terminals
- CALL ATRES2 ; do partial reset of emulator
- atrsm6f:pop ax
- mov curattr,al ; restore saved items
- mov extattr,ah
- test flags.vtflg,ttd463+ttd470 ; D463/D470?
- jz atrsm6g ; z = no
- call frepaint ; repaint new screen
- ret ; D463/D470 gets no other changes
- atrsm6g:mov dx,low_rgt ; text lines (leave status line intact)
- mov mar_top,0
- mov mar_bot,dh ; reset scrolling region
- mov dl,byte ptr low_rgt ; right margin
- mov mar_right,dl
- mov mar_left,0
- xor dx,dx ; new cursor position is 0,0
- mov cursor,dx
- jmp atsetcur ; place it there and return
-
- atrsm7: cmp al,18 ; 18? 18 & 19 = printer support
- jne atrsm8 ; ne = no
- cmp modeset,0 ; resetting?
- jne atrsm7a ; ne = no, setting
- and anspflg,not vtffp ; no form feed after printing
- ret
- atrsm7a:or anspflg,vtffp ; use form feed after printing
- ret
-
- atrsm8: cmp al,19 ; 19, print region?
- jne atrsm9 ; ne = no
- cmp modeset,0 ; resetting?
- jne atrsm8a ; ne = no, setting
- and anspflg,not vtextp ; reset print region to scrolling reg
- ret
- atrsm8a:or anspflg,vtextp ; set print region to whole screen
- ret
-
- atrsm9: cmp al,25 ; ESC [ ? 25 h/l? cursor on/off
- jne atrsm10 ; ne = no
- mov al,4 ; assume cursor to be turned off (4)
- cmp modeset,0 ; resetting (invisible cursor)?
- je atrsm9a ; e = yes
- mov al,1 ; assume underline (1)
- test vtemu.vtflgop,vscursor ; underline?
- jnz atrsm9a ; nz = yes
- inc al ; block (2)
- atrsm9a:mov atctype,al ; save VTxxx cursor type here
- jmp atsctyp ; set the cursor type
-
- ; DECRLM (alt VT320 right/left write)
- atrsm10:cmp al,34 ; ESC [ ? 34 h/l? Invoke special macro
- jne atrsm10b ; ne = no
- and vtemu.vtflgop,not vswdir; writing direction to normal
- and vtemu.vtflgst,not vswdir; writing direction to normal
- cmp modeset,0 ; resetting?
- jne atrsm10a ; ne = no, setting
- mov decrlm,0 ; writing direction to left to right
- ret
- atrsm10a:mov decrlm,1 ; writing direction to right to left
- ret
- ; DECHEBM (alt VT320 keyboard map)
- atrsm10b:cmp al,35 ; ESC [ ? 35 h/l? Invoke special macro
- jne atrsm10d ; ne = no
- cmp modeset,0 ; resetting?
- jne atrsm10c ; ne = no, setting
- call fvtkrmac ; perform on-line macro
- ret
- ; code is located in file msy
- atrsm10c:call fvtksmac ; do set macro
- ret
-
- atrsm10d:cmp al,36 ; DECHEM Hebrew encoding mode?
- jne atrsm11 ; ne = no
- cmp modeset,0 ; resetting?
- jne atrsm10e ; ne = no
- mov al,13 ; Hebrew NRC
- mov ah,al ; GR = GL = 13
- or vtemu.vtflgop,vsnrcm ; set NRC active bit
- or vtemu.vtflgst,vsnrcm
- and vtemu.vtflgop,not vscntl ; no 8-bit controls
- jmp short atrsm10f
- atrsm10e:mov al,17 ; DEC Multinational set (17)
- xor ah,ah ; GLeft is ASCII (0)
- and vtemu.vtflgop,not vsnrcm ; clear NRC active bit
- and vtemu.vtflgst,not vsnrcm
- atrsm10f:mov vtemu.vtchset,al
- mov bx,offset emubuf ; temp table of char set idents
- xchg ah,al ; order correctly
- mov [bx],ax ; char sets for G0..G3
- mov [bx+2],ax
- call chrsetup ; invoke NRC
- ret
-
- atrsm11:cmp al,38 ; 38? Enter Tek sub-mode. VT340 seq
- jne atrsm12 ; ne = no
- cmp modeset,1 ; setting mode (ESC [ ? 38 h)?
- jne atrsm12 ; ne = no, ignore sequence
- test denyflg,tekxflg ; is auto Tek mode disabled?
- jnz atrsm12 ; nz = yes, just ignore command
- call atsc ; save cursor and associated data
- xor al,al ; enter with this received character
- call TEKEMU ; go to Tektronix Emulator, al=null
- jmp atnorm
-
- atrsm12:cmp al,42 ; 42, use NRC 7-bit command?
- jne atrsm15 ; ne = no
- test flags.vtflg,ttvt320+ttvt220 ; VT320/VT220 mode?
- jz atrsm14 ; z = no
- cmp vtemu.vtchset,0 ; ASCII?
- je atrsm14 ; e = yes, no NRC
- cmp vtemu.vtchset,13 ; highest NRC ident?
- ja atrsm14 ; a = not NRC
- cmp modeset,0 ; resetting?
- je atrsm13 ; e = yes
- or vtemu.vtflgop,vsnrcm ; set NRC flag bit
- jmp chrdef ; and set NRC characters
- atrsm13:mov ax,vtemu.vtflgop ; run time flags
- and vtemu.vtflgop,not vsnrcm ; turn off NRC flag bit
- or vtemu.vtflgop,vscntl ; turn on 8-bit controls
- jmp chrdef
- atrsm14:ret
- atrsm15:cmp al,66 ; 66, keypad to applications mode?
- jne atrsm16 ; ne = no
- test flags.vtflg,ttvt320+ttvt220 ; VT320/VT220 mode?
- jz atrsm16 ; z = no
- mov ax,deckpam ; bit to control
- jmp atrsflg ; control the flag and return
- atrsm16:ret
-
- ; VT340 CSI number $ | number is 0 or 80 for 80 cols, 132 for 132 columns
- ; DECSCPP, set columns per page
- atscpp: cmp inter,'$' ; correct intermediate letter?
- jne atscpp2 ; ne = no, ignore
- cmp ninter,1 ; one intermediate?
- jne atscpp2 ; ne = no, ignore
- mov modeset,1 ; assume 132 columns wanted
- cmp param,80 ; 80 or 132 columns?
- ja atscpp1 ; a = 132 columns
- mov modeset,0 ; set to 80 columns
- atscpp1:mov al,3 ; set up CSI ? 3 h/l command
- jmp atrsm6 ; process that command
- atscpp2:ret
-
- ; Heath-19 ESC [ > Ps h or l where Ps = 1, 4, 7, or 9
- htrsm1: cmp al,1 ; 25th line?
- jne htrsm4 ; ne = no
- and h19stat,not h19l25 ; clear 25th line bit
- cmp modeset,0 ; clearing?
- je htrsm1a ; e = yes
- or h19stat,h19l25 ; set bit
- jmp htrsmx ; we are done
- htrsm1a:mov ah,byte ptr low_rgt+1 ; point to status (25th) line
- inc ah ; which is here
- xor al,al ; from column 0
- mov bh,ah ; to same line
- mov bl,byte ptr low_rgt ; physical width
- call vtsclr ; disabling status line clears it
- ret
-
- htrsm4: cmp al,4 ; 4, block/line cursor?
- jne htrsm5 ; ne = no
- and h19ctyp,4 ; save on/off bit (4)
- cmp modeset,0 ; reset?
- je htrsm4a ; e = yes
- or h19ctyp,2 ; remember block kind here
- jmp atsctyp
- htrsm4a:or h19ctyp,1 ; remember underline kind here
- jmp atsctyp
-
- htrsm5: cmp al,5 ; 5, on/off cursor?
- jne htrsm7 ; ne = no
- cmp modeset,0 ; on?
- je htrsm5a ; e = yes
- or h19ctyp,4 ; remember off state in this bit
- jmp atsctyp
- htrsm5a:and h19ctyp,not 4 ; set cursor on
- jmp atsctyp
-
- htrsm7: cmp al,7 ; 7, alternate application keypad?
- jne htrsm8 ; ne = no
- mov ax,deckpam ; get keypad application mode bit
- jmp atrsflg ; set or reset appl keypad mode
-
- htrsm8: cmp al,8 ; 8, received CR => CR/LF?
- jne htrsm9
- and h19stat,not h19alf ; clear autoline feed bit
- cmp modeset,0 ; resetting?
- je htrsmx ; yes
- or h19stat,h19alf ; turn on the mode
- ret
-
- htrsm9: cmp al,9 ; 9, auto newline mode? (add cr to lf)
- jne htrsmx ; ne = no
- mov ax,anslnm ; get the bit
- jmp atrsflg ; set or reset newline mode
- htrsmx: ret ; ignore the code
-
- atrsflg:cmp modeset,0 ; reset?
- je atrsf1 ; e = yes, reset it
- or vtemu.vtflgop,ax ; set, OR in the flag
- test ax,decanm ; changing ansi mode?
- jz atrsfx ; z = no
- cmp flags.vtflg,ttheath ; in Heath-19 mode?
- je atrsfx ; e = yes, don't flip terminal kinds
- mov ax,oldterm ; terminal type at startup
- mov flags.vtflg,ax ; restore it
- ret
- atrsf1: not ax ; reset bit, complement
- and vtemu.vtflgop,ax ; clear the bit
- not ax ; recover the bit
- test ax,decanm ; changing ansi mode?
- jz atrsfx ; z = no
- cmp flags.vtflg,ttheath ; in Heath-19 mode?
- je atrsfx ; e = yes, don't flip terminal kinds
- mov flags.vtflg,ttvt52 ; say VT52 now
- atrsfx: ret
- ; Set/Clear Origin mode
- atrsom: test dspstate,dsptype ; on status line?
- jz atrsom1 ; z = no
- ret ; else ignore this command
- atrsom1:cmp modeset,0 ; clearing DEC origin mode?
- jne atrsom2 ; ne = no, setting
- and vtemu.vtflgop,not decom ; reset Origin mode
- xor dx,dx ; go to the home position
- jmp atsetcur ; set cursor and return
- atrsom2:or vtemu.vtflgop,decom ; set Origin mode
- mov dx,cursor ; get the cursor
- xor dl,dl ; go to right margin
- mov dh,mar_top ; go to home of scrolling region
- jmp atsetcur ; set the cursor and return
-
- atrsscnm:cmp modeset,0 ; resetting?
- je atrss1 ; e = yes, reset
- test vtemu.vtflgop,vsscreen ; setting, set already?
- jnz atrss3 ; nz = yes, don't do it again
- or vtemu.vtflgop,vsscreen ; set and tell Status display
- jmp short atrss2 ; do it
-
- atrss1: test vtemu.vtflgop,vsscreen ; resetting, reset already?
- jz atrss3 ; z = yes, don't do it again
- and vtemu.vtflgop,not vsscreen ; clear and tell Status
- ; fall through to atrss2
-
- ; Note: This is also called from the stblmds initialization routine.
- ; Reverse video the entire screen, update scbattr and curattr to match.
- atrss2: push ax
- mov ah,scbattr ; current screen attributes
- call revideo ; reverse them
- mov scbattr,ah ; set screen background attribute
- mov ah,curattr ; get current cursor attribute
- call revideo ; reverse it
- mov curattr,ah ; store it
- call revscn ; reverse everything on the screen
- pop ax
- atrss3: ret
-
- ; Self tests DECTST
- atctst: cmp inter,0 ; any intermediate char?
- jne atcts3 ; ne = yes, not a selftest command
- cmp param,2 ; VT102 selftest?
- je atcts1 ; e = yes
- cmp param,4 ; VT320 selftest?
- jne atcts6 ; ne = no
- atcts1: test dspstate,dsptype ; cursor is on status line?
- jz atcts2 ; z = no
- push param ; save first parameter
- mov ah,inter ; and first intermediate char
- push ax
- mov param,0 ; select main display
- mov inter,'$' ; setup proper intermediate
- call atssdt ; select status line of off
- call atsasd ; select main display
- pop ax
- pop param ; restore parameter
- mov inter,ah ; and intermediate char
- atcts2: xor al,al ; init test weight
- mov di,offset atcts4 ; routine to call
- call atreps ; repeat for all parms
- test al,80H ; reset?
- jz atcts3 ; z = no, return
- jmp atreset ; reset everything
- atcts3: ret
-
- atcts4: or si,si ; initial arg?
- jz atcts5 ; z = yes, skip it (examined above)
- cmp param[si],1 ; power up test (0, 1) included?
- ja atcts5 ; a = no, ignore printer/comms/repeats
- or al,80H ; say we want reset
- atcts5: ret
-
- atcts6: cmp nparam,0 ; absence of parameters?
- jne atcts5 ; ne = no, ignore sequence
- jmp athoney ; try Honeywell ESC [ y ident response
-
- atalign proc near ; Align screen, fill screen with 'E's
- mov al,'E' ; char to use as filler
- test dspstate,dsptype ; is cursor on status line?
- jz atalig1 ; z = no
- ret ; yes, ignore the command
- atalig1:cmp flags.modflg,0 ; is mode line off?
- je atalig2 ; e = yes
- and yflags,not modoff ; say it's on
- mov flags.modflg,1 ; and owned by us
- atalig2:push ax ; save displayed char
- push vtemu.vtflgst ; save setup flags
- mov ax,vtemu.vtflgop ; operational flags
- and ax,deccol ; get 80/132 column indicator
- and vtemu.vtflgst,not deccol ; clear for set below
- or vtemu.vtflgst,ax ; set it so reset preserves it
- call atreset ; clear system
- pop vtemu.vtflgst ; recover setup flags
- or vtemu.vtflgop,decawm ; set wrap
- mov cl,byte ptr low_rgt ; number of columns-1
- inc cl
- mov al,byte ptr low_rgt+1 ; number of rows-1
- inc al
- mul cl ; ax = number of chars on screen
- mov cx,ax
- pop ax ; recover displayed char in AL
- mov emubuf,al ; keep it here while looping
- atalig3:push cx
- mov al,emubuf ; write screen full of this char
- call atnrm ; write the 'E' or whatever
- pop cx
- loop atalig3 ; cx times
- ret
- atalign endp
-
-
- ; Reports
- atreqt: cmp param,1 ; want report?
- jbe atreq1 ; be = yes
- atreq0: ret ; Gee, must have been an echo
-
- atreq1: test flags.vtflg,ttvt102+ttvt100+tthoney ; VT102 etc?
- jz atreq0 ; z = no, ignore
- mov ttyact,0 ; group output for networks
- mov al,CSI
- call prtbout ; send CSI or ESC [
- mov al,'3' ; we report only upon request
- cmp param,0 ; was argument a zero?
- jne atreq1b ; ne = no
- mov al,'2' ; yes
- atreq1b:call prtbout
- mov al,';' ; separate
- call prtbout
- mov bl,parcode ; get the parity code
- xor bh,bh
- mov al,partab[bx] ; get VT100 parity code
- push ax ; save parity code
- call prtnout ; send number to the port
- mov al,';' ; separate
- call prtbout
- mov al,'2' ; assume 7 data bits
- pop bx ; get parity code into bl
- cmp bl,1 ; is parity none?
- jne atreq2 ; ne = no, so 7 data bits
- test flags.remflg,d8bit ; 8 bit display?
- jz atreq2 ; z = no
- mov al,'1' ; must be eight
- atreq2: call prtbout ; send it to the port
- mov al,';'
- call prtbout
- mov bl,baudidx ; baud rate index
- xor bh,bh
- mov al,baudtab[bx] ; get DEC baud rate code
- push ax
- call prtnout ; sending speed index
- mov al,';'
- call prtbout
- pop ax
- cmp bl,lbaudtab-1 ; using the split speed entry?
- jne atreq2a ; ne = no
- mov al,[bx+1] ; get trailing receive speed (75 baud)
- atreq2a:call prtnout ; receiving speed index
- mov al,';'
- call prtbout
- mov al,'1' ; clock rate multiplier is always 1
- call prtbout
- mov al,';'
- call prtbout
- mov al,'0' ; Flags are always zero (no STP)
- call prtbout
- mov ttyact,1 ; end group output for networks
- mov al,'x'
- call prtbout
- ret
-
- ; Single Controls
- ; Note DEC manual incorrectly says DECSCL's do a hard rather than soft reset
- decscl: cmp inter,'!' ; "CSI ! p" soft reset?
- jne decsc0 ; ne = no
- jmp atsres ; do a soft reset
-
- decsc0: cmp inter,'"' ; "CSI Psc; Ps1 " p" operating level?
- je decsc1 ; e = yes
- cmp inter,'$' ; "CSI Pn $ p" DECRQM?
- jne decsc0a ; ne = no, ignore others
- jmp decsc5 ; do isolated controls report
- decsc0a:ret ; else ignore
- decsc1: cmp param,61 ; Psc, select VT100?
- jne decsc2 ; ne = no
- mov flags.vtflg,ttvt102 ; set VT102
- mov oldterm,ttvt102 ; and remember it
- and vtemu.vtflgop,not vscntl ; turn off 8-bit controls
- mov al,anspflg ; preserve screen print flag
- push ax
- call atsres ; do soft reset of emulator
- pop ax
- mov anspflg,al
- ret
- decsc2: cmp param,62 ; go to VT2xx level?
- jne decsc3 ; ne = no
- test flags.vtflg,ttvt320+ttvt102 ; at VT300/VT102 level now?
- jnz decsc3a ; nz = yes, don't change types
- mov flags.vtflg,ttvt220 ; set VT220 mode
- mov oldterm,ttvt220
- jmp short decsc3b ; finish up
-
- decsc3: cmp param,63 ; go to VT300 level?
- jne decsc4 ; ne = no
- decsc3a:mov flags.vtflg,ttvt320 ; set VT320 mode
- mov oldterm,ttvt320
- decsc3b:cmp param[2],2 ; Ps1, range here is 0, 1, 2
- ja decsc4 ; a = out of range, ignore
- mov al,anspflg ; preserve screen print flag
- push ax
- call atsres ; do soft reset of emulator
- pop ax
- mov anspflg,al
- and vtemu.vtflgop,not vscntl ; turn off 8-bit controls
- cmp param[2],1 ; select 7-bit controls?
- je decsc4 ; e = yes, we have done so
- or vtemu.vtflgop,vscntl ; turn on 8-bit controls
- decsc4: ret
- ; single controls report request
- decsc5: cmp lparam,'?' ; want DEC Private modes?
- jne decsc5a ; ne = no
- call decscpre ; do standard prefix
- mov al,'2' ; assume mode is reset
- call decsc20 ; do DEC Private mode report
- jmp decscend ; do end of sequence
- decsc5a:cmp inter,0 ; intermediate char?
- je decsc5b ; e = no, ignore
- call decscpre ; do standard prefix
- mov al,'2' ; assume mode is reset
- call decsc5c ; do ANSI report
- jmp decscend ; do end of sequence
- decsc5b:ret ; else return failure
-
- decsc5c:mov cx,param ; ANSI report:
- cmp cx,2 ; 2, Keyboard action?
- jne decsc6 ; ne = no
- ret
- decsc6: cmp cx,3 ; control representation?
- jne decsc7 ; ne = no
- ret ; say reset(acting on controls)
- decsc7: cmp cx,4 ; 4, Insert/Replace mode?
- jne decsc8 ; ne = no
- cmp insmod,0 ; insert mode off?
- je decsc7a ; e = yes, off
- dec al ; say is on
- decsc7a:ret
- decsc8: cmp cx,10 ; 10, Horizontal editing?
- jne decsc9 ; ne = no
- mov al,'4' ; permanently reset
- ret
- decsc9: cmp cx,12 ; 12, Send/Receive (local echo)?
- jne decsc11 ; ne = no
- test yflags,lclecho ; echoing on?
- jz decsc12 ; z = no
- dec al ; say set
- ret
- decsc11:cmp cx,20 ; 20, new line mode?
- jne decsc13 ; ne = no
- test vtemu.vtflgop,anslnm ; new line set?
- jz decsc12 ; z = no, reset
- dec al ; say set
- decsc12:ret
- decsc13:mov al,'0' ; say not recognized
- ret
-
- ; DEC Private mode report
- decsc20:mov cx,param
- cmp cx,1 ; 1, cursor keys?
- jne decsc22 ; ne = no
- test vtemu.vtflgop,decckm ; set?
- jz decsc31 ; z = no, reset
- dec al
- ret
- decsc22:cmp cx,2 ; 2, ANSI mode
- jne decsc24 ; ne = no
- test vtemu.vtflgop,decanm ; set?
- jz decsc31 ; z = no, reset
- dec al
- ret
- decsc24:cmp cx,3 ; 3, column
- jne decsc26 ; ne = no
- test vtemu.vtflgop,deccol ; 132 column mode set?
- jz decsc31 ; z = no, reset (80 columns)
- dec al
- ret
- decsc26:cmp cx,4 ; 4, scrolling mode
- je decsc31 ; e = yes always say reset (jump)
- ;
- cmp cx,5 ; 5, screen
- jne decsc28 ; ne = no
- test vtemu.vtflgop,decscnm ; set (light background)?
- jz decsc31 ; z = no, reset
- dec al
- ret
- decsc28:cmp cx,6 ; 6, Origin mode?
- jne decsc30 ; ne = no
- test dspstate,dsptype ; on status line?
- jz decsc29 ; z = no, main display
- test dspstate,dspdecom ; main display Origin mode set?
- jz decsc31 ; z = no, reset
- dec al
- ret
- decsc29:test vtemu.vtflgop,decom ; Origin mode set?
- jz decsc31 ; z = no, reset
- dec al
- ret
- decsc30:cmp cx,7 ; 7, autowrap?
- jne decsc32 ; ne = no
- test vtemu.vtflgop,decawm ; set?
- jz decsc31 ; z = no, reset
- dec al
- decsc31:ret ; common return point
- decsc32:cmp cx,8 ; 8, autorepeat?
- jne decsc34 ; ne = no
- dec al
- ret ; say set
- decsc34:cmp cx,18 ; 18, print Form Feed?
- jne decsc36 ; ne = no
- test anspflg,vtffp ; set?
- jz decsc31 ; z = no, reset
- dec al
- ret
- decsc36:cmp cx,19 ; 19, printer extent?
- jne decsc38 ; ne = no
- test anspflg,vtextp ; set?
- jz decsc31 ; z = no, reset
- dec al
- ret
- decsc38:cmp cx,25 ; 25, text cursor enabled?
- jne decsc40 ; ne = no
- test atctype,4 ; 4 is off
- jnz decsc31 ; nz = off/disabled
- dec al ; say enabled
- ret
- decsc40:cmp cx,42 ; 42, NRC's
- jne decsc42 ; ne = no
- test flags.vtflg,ttvt320+ttvt220 ; VT320/VT220?
- jz decsc31 ; z = no
- test vtemu.vtflgop,vsnrcm ; NRC's active?
- jz decsc31 ; z = no
- dec al ; say enabled
- ret
- decsc42:cmp cx,66 ; 66, numeric keypad?
- jne decsc44 ; ne = no
- test vtemu.vtflgop,deckpam ; set?
- jz decsc31 ; z = no, reset
- dec al ; say set
- ret
- decsc44:cmp cx,68 ; 68, keyboard usage?
- jne decsc45 ; ne = no
- mov al,'4' ; say always typewriter mode
- ret
- decsc45:mov al,'0' ; say unknown kind
- ret
-
- decscpre:mov ttyact,0 ; group output for networks
- mov al,CSI ; do standard report beginning
- call prtbout
- mov al,byte ptr param ; get parameter
- call prtnout ; send the number
- mov al,';'
- call prtbout
- ret
-
- decscend:call prtbout ; do standard rpt end, send char in al
- mov al,'$'
- call prtbout
- mov ttyact,1 ; end group output for networks
- mov al,'y'
- call prtbout
- ret
-
- ; DEC style Soft Reset
- ; Note: graphics rendition is NOT changed by soft reset, DEC manual is wrong.
- atsres proc near ; do soft reset of terminal
- test dspstate,dsptype ; on status line?
- jz atsres1 ; z = no, on main display
- mov param,0
- mov inter,'$' ; setup entry for atsasd
- call atsasd ; select main display
- atsres1:and vtemu.vtflgop,not(decawm+decckm+deckpam+decom) ; these go off
- mov insmod,0 ; insert mode off
- mov mar_top,0 ; reset scrolling margins
- mov al,byte ptr low_rgt+1
- mov mar_bot,al ; to full screen
- mov anspflg,0 ; clear printer flag
- mov al,1 ; restore cursor, assume underline (1)
- test vtemu.vtflgop,vscursor ; underline?
- jnz atsres2 ; nz = yes
- inc al ; block (2)
- atsres2:mov atctype,al ; save VTxxx cursor type here
- call atsctyp ; set the cursor type
- push cursor
- mov cursor,0 ; set save cursor to Home
- call atsc ; save attributes
- pop cursor ; restore active cursor
- call chrdef ; set default character set
- call fmodlin ; rewrite mode line
- ret
- atsres endp
- ; DECRQSS/DECRPSS Control Settings
-
- ; Handle DCS ... q string ST
- atcrq: cmp ninter,1 ; one intermediate?
- je atcrq1 ; e = yes
- ja atcrq0 ; a = too many
- jmp atcrqq ; none, do Sixel DCS params q...ST
- atcrq0: mov ninter,0 ; set up atdcsnul for proper form
- mov ttstate,offset atdcsnul ; not understood, consume til ST
- ret
-
- atcrq1: cmp inter,'$' ; correct intermediate?
- jne atcrq0 ; ne = no
- cmp nparam,0 ; and no parameters?
- jne atcrq0 ; ne = have some, not ours
- mov ttstateST,offset atcrq4 ; set state for ST arrival
- mov ttstate,offset atcrq2 ; next state gets string contents
- mov emubufc,0 ; clear buffer counter
- mov word ptr emubuf,0 ; empty start of buffer
- ret
- atcrq2: mov bx,emubufc ; count of chars in string buffer
- cmp bx,emubufl ; too many?
- jae atcrq3 ; ae = too many, ignore extras
- mov emubuf[bx],al ; store the char
- inc emubufc ; count it
- atcrq3: ret
- ; here after ST has been seen
- atcrq4: cmp emubufc,2 ; max string chars we want
- jbe atcrq4a ; be = ok
- jmp atnorm ; a = too many, ignore
- atcrq4a:mov ax,word ptr emubuf ; get first two chars
- cmp ax,'}$' ; select active display?
- jne atcrq5 ; ne = no
- jmp atcrqd ; do the routine
- atcrq5: cmp ax,'p"' ; set conformance level?
- jne atcrq7 ; ne = no
- jmp atcrqp
- atcrq7: cmp ax,'~$' ; set status line type
- jne atcrq8
- jmp atcrqt
- atcrq8: cmp ax,'r' ; set top and bottom margins?
- jne atcrq9
- jmp atcrqr
- atcrq9: cmp ax,'m' ; set graphic rendition?
- jne atcrq10
- jmp atcrqm
- atcrq10:jmp atcrqxx ; unknown command
- ; DCS $ q response routines
- atcrqr: call atcrqbeg ; 'r', top/bottom margins
- test dspstate,dsptype ; doing status line display?
- jz atcrqr2 ; z = no
- mov al,byte ptr dspmsave ; get saved top margin
- inc al
- call prtnout
- mov al,';'
- call prtbout
- mov al,byte ptr dspmsave+1 ; get saved bottom margin
- jmp short atcrqr3 ; finish up
- atcrqr2:mov al,mar_top ; top margin
- inc al ; move to 1,1 system
- call prtnout
- mov al,';'
- call prtbout
- mov al,mar_bot
- atcrqr3:inc al ; move to 1,1 system
- call prtnout
- mov al,'r' ; final char
- jmp atcrqend ; do epilogue
-
- atcrqm: call atcrqbeg ; 'm', graphics rendition
- mov al,'0' ; say start with all attributes off
- call prtbout
- call getbold ; returns ah with bold attr or 0
- or ah,ah ; bold set?
- jz atcrqm2 ; z = no
- mov al,';'
- call prtbout
- mov al,'1' ; say bold is on
- call prtbout
- atcrqm2:call getunder ; underline
- or cl,cl ; underline on?
- jz atcrqm3 ; z = no, do next
- mov al,';'
- call prtbout
- mov al,'4' ; say underlining is on
- call prtbout
- atcrqm3:mov ah,scbattr
- call getblink ; blinking
- or ah,ah ; blinking on?
- jz atcrqm4 ; z = no
- mov al,';'
- call prtbout
- mov al,'5' ; say blinking is on
- call prtbout
- atcrqm4:test extattr,att_rev ; chars in reversed video?
- jz atcrqm5 ; z = no
- mov al,';'
- call prtbout
- mov al,'7' ; say underlining is on
- call prtbout
- atcrqm5:mov al,'m' ; final char
- jmp atcrqend ; do epilogue
-
- atcrqd: call atcrqbeg ; '$}', writing to screen/status line
- mov al,'0' ; assume writing to main display
- test dspstate,dsptype ; get type of display
- jz atcrqd2 ; z = main display
- inc al ; say writing to mode line
- atcrqd2:call prtbout
- mov al,'$' ; final chars
- call prtbout
- mov al,7dh ; right curly brace
- jmp atcrqend ; do epilogue
-
- atcrqt: call atcrqbeg ; '$~', status line
- mov al,'0' ; assume mode line is off
- test yflags,modoff ; is mode line off?
- jnz atcrqt2 ; nz = yes
- mov al,'2' ; mode line is on and host writable
- atcrqt2:call prtbout
- mov al,'c' ; final chars
- call prtbout
- mov al,7eh ; tilde
- jmp atcrqend ; do epilogue
- ; '"p' set conformance level
- atcrqp: cmp oldterm,ttvt100 ; main-mode terminal is VT100?
- je atcrqp2 ; e = yes
- cmp oldterm,tthoney ; Honeywell?
- je atcrqp2 ; e = yes
- cmp oldterm,ttvt102 ; VT102?
- je atcrqp2 ; e = yes
- cmp oldterm,ttvt320 ; how about VT320?
- je atcrqp2 ; e = yes
- jmp atcrqxx ; say invalid request
- atcrqp2:mov ttyact,0 ; group output for networks
- mov al,DCS ; '"p', conformance level
- call prtbout
- mov al,'0' ; valid request
- call prtbout
- mov al,'$'
- call prtbout
- mov al,61 ; assume VT102
- cmp oldterm,ttvt100 ; VT100?
- je atcrqp2a ; e = yes
- cmp oldterm,tthoney ; Honeywell
- je atcrqp2a ; e = yes
- cmp oldterm,ttvt102 ; are we a VT102?
- jne atcrqp3 ; ne = no
- atcrqp2a:call prtnout
- jmp short atcrqp5 ; finish the report
-
- atcrqp3:mov al,63 ; say VT320
- call prtnout
- mov al,';'
- call prtbout
- mov al,'2' ; assume 8-bit controls are on
- test vtemu.vtflgop,vscntl ; 8-bit controls active?
- jnz atcrqp4 ; nz = yes
- mov al,'1' ; else say only 7-bit controls
- atcrqp4:call prtbout
- atcrqp5:mov al,'"' ; final characters
- call prtbout
- mov al,'p'
- jmp atcrqend ; do epilogue
-
- atcrqbeg:mov ttyact,0 ; group output for networks
- mov al,DCS ; report prologue
- call prtbout
- mov al,'0' ; valid request
- call prtbout
- mov al,'$'
- jmp prtbout
-
- atcrqend:call prtbout ; report epilogue, al has char
- mov ttyact,1 ; end group output for networks
- mov al,STCHR ; string terminator
- jmp prtbout
-
- atcrqxx:mov ttyact,0 ; group output for networks
- mov al,DCS ; report invalid request
- call prtbout
- mov al,'1' ; invalid request
- call prtbout
- mov al,'$'
- cmp emubufc,1 ; any first char?
- jb atcrqend ; b = no
- call prtbout
- mov al,emubuf ; first string char
- cmp emubufc,2 ; two string chars?
- jne atcrqend ; ne = no
- call prtbout
- mov al,emubuf+1 ; second string char
- jmp atcrqend ; do epilogue
-
- ; DCS P1; P2; P3 <char> Sixel command
- atcrqq: cmp dcsstrf,'q' ; final char of 'q'? Sixel draw
- je atcrqq1 ; e = yes
- cmp dcsstrf,'p' ; 'p', restore palette?
- jne atcrqq0 ; ne = no
- cmp dinter,'$' ; DCS 2 $ p?
- jne atcrqq0 ; ne = no
- cmp param,2 ; this too?
- jne atcrqq1 ; ne = no
- call tekinq ; get Tek screen state
- jmp tekrcol ; restore palette
-
- atcrqq0:mov ninter,0 ; setup atdcsnul for proper form
- jmp atdcsnul ; consume unknown command
- atcrqq1:test denyflg,tekxflg ; is auto Tek mode disabled?
- jnz atcrqq0 ; nz = yes, consume
- mov di,offset emubuf ; temp buffer
- mov byte ptr [di],escape ; do ESC ^L to erase screen
- inc di
- mov byte ptr [di],FF
- inc di
- mov byte ptr [di],escape ; start DCS
- inc di
- mov byte ptr [di],'P'
- inc di
- mov ax,dparam[0] ; get first parameter
- call fdec2di
- mov byte ptr [di],';'
- inc di
- mov ax,dparam[2] ; get second parameter
- call fdec2di ; write ascii value
- mov byte ptr [di],';'
- inc di
- mov ax,dparam[4] ; get third parameter
- call fdec2di ; write ascii value
- mov al,dcsstrf
- mov byte ptr [di],al ; final char
- mov byte ptr [di+1],0 ; terminator
- mov di,offset emubuf
- mov al,yflags ; get yflags
- and al,capt ; save logging bit
- push ax
- and yflags,not capt ; turn off logging bit
- atcrqq2:mov al,[di]
- inc di
- or al,al ; at the end?
- jz atcrqq3 ; z = yes
- push di
- call tekemu ; feed Tek emulator this string
- pop di
- jmp short atcrqq2 ; do another string member
- atcrqq3:mov chcontrol,1 ; turn on full cell char writing
- pop ax ; recover logging bit
- or yflags,al ; restate logging bit
- jmp atnorm
-
- ; State machine to process DCS strings of type "p" (restore color palette)
- ; Enter with "p" char in AL.
- tekrcol proc near
- mov ttstate,offset tekrco1 ; next state is get parameter
- mov ttstateST,offset tekrcost ; go here on ST
- push es
- push ds
- pop es
- mov cx,5 ; five words
- xor ax,ax
- mov di,offset param ; clear parameters Pc,Pu,Px,Py,Pz
- cld
- rep stosw
- pop es
- mov nparam,0 ; work on initial parameter first
- ret
- tekrco1:push bx
- mov bx,nparam ; parameter number
- shl bx,1 ; make it a word index
- mov cx,param[bx] ; accumulated parameter
- call getdec ; accumulate decimal value
- mov param[bx],cx ; remember accumulation
- pop bx
- jnc tekrcos1 ; nc = got a digit char
- inc nparam ; say have another complete parameter
- cmp al,'/' ; this kind of separator?
- je tekrco3 ; e = yes, finish
- cmp al,';' ; break char is separator?
- jne tekrco4 ; ne = no, decode current sequence
- tekrco3:cmp nparam,5 ; have 5 params already?
- jb tekrcos1 ; n = no, continue reading
- tekrco4:call tekrpal ; process parameters in msgibm file
- jmp tekrcol ; start over on next field
-
- tekrcost:mov ttstate,offset atnrm ; get here on ST
- mov ttstateST,offset atnorm ; default ST completion state
- cmp nparam,5 ; enough parameters to finish cmd?
- jb tekrcos1 ; b = no, abandon it
- call tekrpal ; update from last data item
- tekrcos1:ret
- tekrcol endp
-
- ; Accumulate decimal value in CX using ascii char in al.
- ; Return with value in CX. Return carry clear if ended on a digit,
- ; return carry set and ascii char in al if ended on a non-digit.
- getdec proc near
- cmp al,'0' ; a number?
- jb getdecx ; b = no, quit
- cmp al,'9'
- ja getdecx ; a = not a number, quit
- sub al,'0' ; remove ascii bias
- xchg cx,ax ; put char in cx, decimal value in ax
- push dx ; save reg
- push bx
- mov bx,10
- mul bx ; times ten for a new digit
- pop bx
- pop dx ; recover reg, ignore overflow
- add al,cl ; add current digit
- adc ah,0 ; 16 bits worth
- xchg ax,cx ; rpt cnt back to cx
- clc ; say found a digit
- ret
- getdecx:stc ; say non-digit (in al)
- ret
- getdec endp
- ; Device Status Reports
- atdsr: mov di,offset atdsr1 ; routine to call
- call atreps ; do for all parms
- ret
- ; DSR workers
- atdsr1: mov ax,param[si]
- cmp lparam,0 ; any intermediate?
- jne atdsr2 ; ne = yes, an intermediate
- cmp ax,5 ; operating status report?
- je rpstat ; e = yes
- cmp ax,6 ; cursor position report?
- je rpcup ; e = yes
- ret
- atdsr2: cmp lparam,'?' ; DEC mode queries for below?
- jne atdsr3 ; no, skip them
- cmp ax,6 ; VT340 cursor report?
- je rpcup ; e = yes
- cmp ax,15 ; printer status report?
- je rpstap ; e = yes
- cmp ax,25 ; UDK status?
- jne atdsr3 ; ne = no
- jmp rpudk ; do udk status rpt
- atdsr3: cmp ax,26 ; keyboard type?
- jne atdsr4 ; ne = no
- jmp rpkbd ; do keyboard type report
- atdsr4: cmp ax,256 ; WordPerfect Tek screen query?
- jne atdsr5 ; ne = no
- jmp tekrpt ; do Tek report
- atdsr5: ret ; must have been an echo
-
- rpstat: mov ttyact,0 ; group output for networks
- mov al,CSI ; operating status query
- call prtbout
- mov al,'0' ; tell them we think we are OK
- call prtbout
- mov ttyact,1 ; end group output for networks
- mov al,'n'
- call prtbout
- ret
-
- rpcup: mov ttyact,0 ; group output for networks
- mov al,CSI ; cursor position report
- call prtbout
- mov al,byte ptr cursor+1 ; get row
- inc al ; map to origin at 1,1 system
- test vtemu.vtflgop,decom ; Origin mode set?
- jz rpcup1 ; z = no
- sub al,mar_top ; subtract off top margin
- rpcup1: call prtnout ; output the number
- mov al,';'
- call prtbout
- mov al,byte ptr cursor ; column number
- inc al ; map to origin at 1,1 system
- call prtnout
- mov ttyact,1 ; end group output for networks
- mov al,'R' ; final char
- call prtbout
- ret
-
- rpstap: mov ttyact,0 ; group output for networks
- mov al,CSI ; printer port query
- call prtbout ; send CSI or ESC [ ? 10 or 13 n
- mov al,'?' ; 10 = printer ready, 13 = not ready
- call prtbout
- mov al,'1'
- call prtbout
- mov ah,ioctl ; get printer status, via DOS
- mov al,7 ; status for output
- push bx
- mov bx,4 ; std handle for system printer
- int dos
- pop bx
- jc rpstap1 ; c = call failed
- cmp al,0ffh ; code for Ready
- jne rpstap1 ; ne = not ready
- mov al,'0' ; ready, send final digit
- jmp short rpstap2
- rpstap1:mov al,'3' ; not ready, say printer disconnected
- rpstap2:call prtbout
- mov ttyact,1 ; end group output for networks
- mov al,'n' ; final char of response
- call prtbout
- ret
-
- rpudk: mov ttyact,0 ; group output for networks
- mov al,CSI ; response to UDK locked query
- call prtbout
- mov al,'?'
- call prtbout
- mov al,20 ; say keys are unlocked (locked=21)
- call prtnout
- mov ttyact,1 ; end group output for networks
- mov al,'n' ; final char
- call prtbout
- ret
-
- rpkbd: mov ttyact,0 ; group output for networks
- mov al,CSI ; response to kbd type query
- call prtbout
- mov al,'?'
- call prtbout
- mov al,27 ; keyboard dialect follows
- call prtnout
- mov al,';'
- call prtbout
- mov bl,vtemu.vtchset ; get Kermit NRC code (0-13)
- xor bh,bh
- mov al,nrckbd[bx] ; get DEC keyboard code from table
- call prtnout
- mov ttyact,1 ; end group output for networks
- mov al,'n'
- call prtbout
- ret
-
- tekrpt: call tekinq ; get Tek screen size and num colors
- push cx ; screen colors
- push bx ; screen width
- push ax ; screen height
- mov ttyact,0 ; group output for networks
- mov al,CSI ; response to Tek query
- call prtbout
- mov al,'?'
- call prtbout
- mov di,offset emubuf ; working buffer
- mov byte ptr [di],0 ; insert terminator
- mov ax,256 ; first parameter
- call fdec2di ; write ascii digits
- mov byte ptr [di],';' ; separator
- inc di
- pop ax ; get screen height
- call fdec2di
- mov byte ptr [di],';' ; separator
- inc di
- pop ax ; get screen width
- call fdec2di
- mov byte ptr [di],';' ; separator
- inc di
- pop ax ; get number screen color (0, 1 or 16)
- call fdec2di
- mov byte ptr[di],'n' ; end of sequence
- inc di
- mov cx,di ; compute string length
- mov di,offset emubuf
- sub cx,di
- tekrpt1:mov al,[di] ; get a string char
- inc di
- cmp cx,1 ; last char?
- ja tekrpt2 ; a = no
- mov ttyact,1 ; end group output for networks
- tekrpt2:call prtbout ; send it
- loop tekrpt1
- ret
-
- atrqtsr:cmp flags.vtflg,ttheath ; Heath-19? ESC [ u
- jne atrqts1 ; ne = no
- cmp nparam,0 ; ought to have no parameters
- jne atrqts2 ; ne = oops, not H-19 command, ignore
- jmp atrc ; H19, restore cursor pos and attrib
-
- atrqts1:cmp inter,'$' ; VT320 Terminal State Rpt DECRQTSR?
- jne atrqts2 ; ne = no
- cmp param,1 ; report required?
- je atrqts4 ; e = yes
- cmp param,2 ; VT340 color palette report?
- jne atrqts1a ; ne = no
- call tekinq ; get Tek screen state
- call tekpal ; do palette report in Tek emulator
- atrqts1a:ret
- atrqts2:cmp inter,'&' ; DECRQUPSS, User preferred Supp Set?
- je atrqts5 ; e = yes
- ret ; else ignore
- atrqts4:mov al,DCS ; Terminal state report
- call prtbout ; output as 7- or 8-bit quantity
- mov al,byte ptr param
- call prtnout ; output as ascii digits, no echo
- mov al,'$'
- call prtbout ; output char, no echo
- mov al,'s' ; Final char to main DCS part
- call prtbout
- mov al,STCHR ; terminator to empty string
- call prtbout
- ret
-
- atrqts5:mov al,DCS ; User Preferred Supplemental Set
- call prtbout ; report
- mov al,'0' ; assume 94 byte set
- cmp upss,94 ; 94 byte set?
- je atrqts6 ; e = yes
- inc al ; change to 96 byte size
- atrqts6:call prtbout
- mov al,'!'
- call prtbout
- mov al,'u'
- call prtbout
- mov al,upss+1 ; first ident char
- call prtbout
- mov al,upss+2 ; second char, if any
- or al,al
- jz atrqts7 ; z = no second char
- call prtbout
- atrqts7:mov al,STCHR
- call prtbout
- ret
- ; Request Presentation State Report
- atrqpsr:cmp inter,'$' ; proper form?
- jne atrqps1 ; ne = no, ignore
- cmp param,1 ; cursor report?
- je atrqps2 ; e = yes
- cmp param,2 ; tabstop report?
- jne atrqps1 ; ne = no, ignore
- jmp atrqps40 ; do tabstop report
- atrqps1:ret ; else ignore
-
- atrqps2:mov al,DCS ; cursor report, start
- call prtbout
- mov al,'1'
- call prtbout
- mov al,'$'
- call prtbout
- mov al,'u'
- call prtbout
- mov al,dh ; row of cursor
- inc al ; count from 1,1
- call prtnout ; output number
- mov al,';'
- call prtbout
- mov al,dl ; column of cursor
- inc al ; count from 1,1
- call prtnout ; output number
- mov al,';'
- call prtbout
- mov al,'1' ; video page, always 1 for VT320
- call prtbout
- mov al,';'
- call prtbout
- mov al,40h ; start bit field template
- test extattr,att_rev ; reverse video char writing on?
- jz atrqps3 ; z = no
- or al,8 ; set the bit
- atrqps3:call getblink ; ah will be non-zero if blinking
- or ah,ah ; blinking?
- jz atrqps4 ; z = no
- or al,4 ; set the bit
- atrqps4:call getunder ; ah will be non-zero if underlining
- or cl,cl ; underlining?
- jz atrqps5 ; z = no
- or al,2 ; set the bit
- atrqps5:call getbold ; ax will be non-zero if bolding
- or ah,ah ; bold?
- jz atrqps6 ; z = no
- or al,1 ; set the bit
- atrqps6:call prtbout
- mov al,';'
- call prtbout
- mov al,40h ; Satt (Selective params)
- test extattr,att_protect ; is char protected?
- jz atrqps6a ; z = no
- or al,1 ; say char is protected
- atrqps6a:call prtbout ; output required skeleton
- mov al,';'
- call prtbout
- mov al,40h ; Sflag (shift/wrap/origin mode)
- cmp atwrap,0 ; wrap pending?
- je atrqps7 ; e = no
- or al,8 ; set the bit
- atrqps7:cmp SSptr,offset G3set ; SS3: G3 mapped to GL for next char?
- jne atrqps8 ; ne = no
- or al,4 ; set the bit
- atrqps8:cmp SSptr,offset G2set ; SS2: G2 mapped to GL for next char?
- jne atrqps9 ; ne = no
- or al,2 ; set the bit
- atrqps9:test vtemu.vtflgop,decom ; Origin mode set?
- jz atrqps10 ; z = no
- or al,1 ; set the bit
- atrqps10:call prtbout
- mov al,';'
- call prtbout
- mov al,'0' ; Pgl, say which set is in GL
- mov si,GLptr ; setup for worker
- call atrqps30 ; worker returns proper al
- call prtbout
- mov al,';'
- call prtbout
- mov al,'0' ; Pgr, say which set is in GR
- mov si,GRptr ; setup for worker
- call atrqps30 ; worker returns proper al
- call prtbout
- mov al,';'
- call prtbout
- mov al,40h ; Scss, char set size bit field
- call atrqp15 ; call worker to fill in al
- call prtbout
- mov al,';'
- call prtbout
- mov bx,offset G0set ; Sdesig, get 1-2 letter ident
- call atrqps20 ; G0, let worker fill in response
- mov bx,offset G1set
- call atrqps20 ; G1, let worker fill in response
- mov bx,offset G2set
- call atrqps20 ; G2, let worker fill in response
- mov bx,offset G3set
- call atrqps20 ; G3, let worker fill in response
- mov al,STCHR ; String terminator
- call prtbout
- ret
-
- ; worker for Character set size reporting
- atrqp15:cmp G0set+gsize,96 ; is G0 a 96 byte set?
- jne atrqp16 ; ne = no
- or al,1 ; say 96
- atrqp16:cmp G1set+gsize,96 ; is G1 a 96 byte set?
- jne atrqp17 ; ne = no
- or al,2 ; say 96
- atrqp17:cmp G2set+gsize,96 ; G2 set?
- jne atrqp18
- or al,4 ; say 96
- atrqp18:cmp G3set+gsize,96 ; G3 set?
- jne atrqp19
- or al,8 ; say 96
- atrqp19:ret ; return with al setup
-
- ; worker for Character set ident reporting at atrqps16: et seq
- atrqps20:mov al,[bx+gsize+1] ; Gn set pointer, first letter
- call prtbout
- mov al,[bx+gsize+2] ; second letter
- or al,al ; is there one?
- jz atrqps21 ; z = no, nothing there
- call prtbout
- atrqps21:ret
-
- ; worker. Enter with SI holding GLptr or GRptr and al = '0'
- ; Returns al = '0' .. '3' to match set pointed at
- atrqps30:cmp si,offset G0set ; si points at G0?
- je atrqps31 ; e = yes
- inc al ; try next set
- cmp si,offset G1set ; si points at G1?
- je atrqps31
- inc al
- cmp si,offset G2set ; si points at G2?
- je atrqps31
- inc al ; must be G3
- atrqps31:ret
-
- atrqps40:mov al,DCS ; start tabstop report
- call prtbout
- mov al,'2' ; tabs
- call prtbout
- mov al,'$'
- call prtbout
- mov al,'u'
- call prtbout
- mov cl,mar_right ; right most column number
- inc cl ; number of columns
- xor ch,ch
- push dx ; save dx
- xor dx,dx ; dh for done one output, dl = column
- mov si,offset tabs ; active tabs buffer
- atrqps41:call istabs ; tab inquiry routine, column is in dl
- jnc atrqps43 ; nc = no tab
- or dh,dh ; sent one value already?
- je atrqps42 ; e = no, so no separator
- mov al,';' ; separator (DEC used '/')
- call prtbout
- atrqps42:mov al,dl ; get column
- inc al ; count columns from 1 for host
- call prtnout ; output the number
- inc dh ; say sent a number
- atrqps43:inc dl ; next column, say sent one output
- loop atrqps41 ; do the rest
- pop dx ; recover dx
- mov al,STCHR ; string terminator
- call prtbout
- ret
-
- ; Process Restore Presentation Reports, for cursor and tab stops
- ; Uses bytes dinter+5 and dinter+6 as internal variables
- atrp: cmp dinter,0+'$' ; correct intermediate?
- je atrp1 ; e = yes
- jmp atcrqxx ; send back "illegal restore" response
- atrp1: cmp dparam,1 ; cursor info?
- je atrp4 ; e = yes
- mov modeset,1 ; say setting tabs
- call atrpw ; call worker to do ascii to binary
- dec dl ; count internally from col 0
- call tabset ; set tab in column dl
- atrp3: mov emubufc,0 ; clear the string count
- ret
- ; start cursor info report playback
- atrp4: cmp dinter+5,0 ; our internal counter in vacant byte
- jne atrp5 ; not initial byte
- inc dinter+5 ; point to next item next time
- call atrpw ; ascii to binary worker
- xchg dh,dl ; get row to correct byte
- mov dl,byte ptr cursor+1 ; get column
- jmp atsetcur ; set the cursor
- atrp5: cmp dinter+5,1 ; column?
- jne atrp6
- inc dinter+5 ; point to next item next time
- call atrpw ; ascii to binary worker
- mov dh,byte ptr cursor ; get row
- jmp atsetcur ; set the cursor
- atrp6: cmp dinter+5,2 ; page?
- jne atrp7
- inc dinter+5 ; omit page byte
- ret
- atrp7: cmp dinter+5,3
- jne atrp8
- inc dinter+5 ; Srend
- mov al,emubuf ; string byte
- mov ah,curattr ; attributes field
- ; ought to clear attributes first
- test al,1 ; set bold?
- jz atrp7a ; z = no
- call setbold
- atrp7a: test al,2 ; set underline?
- jz atrp7b ; z = no
- call setunder
- atrp7b: test al,4 ; set blink?
- jz atrp7c ; z = no
- call setblink
- atrp7c: mov curattr,ah ; attributes so far
- test al,8 ; set per char rev video?
- jz atrp7d ; z = no
- call setrev ; set reversed video
- mov curattr,ah ; gather main attributes
- atrp7d: ret
- atrp8: cmp dinter+5,4
- jne atrp9
- inc dinter+5 ; Satt, skip it
- ret
- atrp9: cmp dinter+5,5
- jne atrp10
- inc dinter+5
- mov al,emubuf ; string byte
- mov ah,al
- and ah,8 ; autowrap bit
- mov atwrap,ah ; set it
- mov SSptr,0 ; say no single shift needed
- test al,4 ; SS3 bit?
- jz atrp9a ; z = no
- mov SSptr,offset G3set ; set the pointer
- atrp9a: test al,2 ; SS2 bit?
- jz atrp9b ; z = no
- mov SSptr,offset G2set ; set the pointer
- atrp9b: and vtemu.vtflgop,not decom ; clear origin bit
- test al,1 ; origin mode?
- jz atrp9c ; z = no
- or vtemu.vtflgop,decom ; set origin mode
- atrp9c: ret
- atrp10: cmp dinter+5,6 ; Pgl
- jne atrp11
- inc dinter+5
- mov al,emubuf ; string byte
- call atrpw5 ; call worker to setup bx with ptr
- mov GLptr,bx
- ret
- atrp11: cmp dinter+5,7 ; Pgr
- jne atrp12
- inc dinter+5
- mov al,emubuf ; string byte
- call atrpw5 ; call worker to setup bx with ptr
- mov GRptr,bx
- ret
- atrp12: cmp dinter+5,8 ; Scss
- jne atrp13 ; ne = no
- inc dinter+5
- mov al,emubuf ; string byte
- and al,0fh ; strip ascii bias
- mov dinter+6,al ; save here for Sdesig byte, next
- ret
- atrp13: cmp dinter+5,9 ; Sdesig
- jne atrp14
- inc dinter+5
- mov si,offset emubuf ; string
- xor cx,cx ; init loop counter to 0
- atrp13a:mov al,'(' ; assume G0 is 94 byte set
- add al,cl ; plus loop index to get set pointer
- shr dinter+6,1 ; get set size bit
- jnc atrp13b ; e = correct
- add al,4 ; map to 96 byte indicator
- atrp13b:mov inter,al ; store size byte as intermediate
- mov ninter,1 ; one char
- cld
- atrp13c:lodsb ; next string byte
- test al,not 2fh ; is there a second intermediate byte?
- jnz atrp13d ; nz = no
- mov inter+1,al ; store intermediate
- inc ninter ; count them
- jmp short atrp13c ; try again for a Final char
- atrp13d:push si
- push cx
- mov bx,offset ansesc ; table to use
- call atdispat ; dispatch on final char to set ptr
- pop cx
- pop si
- inc cx
- cmp cx,3 ; doing last one?
- jbe atrp13a ; be = no, do all four
- ret
- atrp14: jmp atcrqxx ; send back "illegal restore" response
-
- ; worker, ascii string to decimal byte
- atrpw: mov cx,emubufc ; length of this string
- jcxz atrpw3 ; nothing there
- mov si,offset emubuf ; address of string
- xor dl,dl ; init final value
- cld
- atrpw2: lodsb ; read a digit
- sub al,'0' ; ascii to numeric
- jc atrpw3 ; c = trouble
- shl dl,1 ; previous contents times 10
- mov dh,dl
- shl dl,1
- shl dl,1
- add dl,dh
- add dl,al ; plus new value
- loop atrpw2 ; do all digits
- atrpw3: ret
- ; char set selector worker
- atrpw5: cmp al,'0' ; bx gets G0set...G3set, based on AL
- jne atrpw5a
- mov bx,offset G0set
- ret
- atrpw5a:cmp al,'1'
- jne atrpw5b
- mov bx,offset G1set
- ret
- atrpw5b:cmp al,'2'
- jne atrpw5c
- mov bx,offset G2set
- ret
- atrpw5c:mov bx,offset G3set
- ret
-
- ; Select Active Display. When selecting the status line make new scrolling
- ; margins be just the status line and force on Origin mode. Save the regular
- ; margins and origin mode for restoration when regular display is re-selected.
- ; Also CSI Pn; Pn; Pn; Pn ~ invokes Lotus macro PRODUCT
- atsasd proc near
- cmp inter,'$' ; correct intermediate?
- jne atsasd1 ; ne = no
- cmp param,1 ; select which display
- jb atsasd4 ; b = select main display
- ja atsasd1 ; a = illegal value
- cmp flags.modflg,2 ; mode line host owned?
- jne atsasd1 ; ne = no, ignore command
- test dspstate,dsptype ; was previous display = status line?
- jz atsasd2 ; z = no
- atsasd1:ret ; else do nothing
-
- atsasd2:push word ptr mar_top ; save scrolling margins
- pop dspmsave ; save scrolling margins
- or dspstate,dsptype ; say status line is active
- mov al,byte ptr low_rgt+1 ; get last text line
- inc al ; status line
- mov mar_top,al
- mov mar_bot,al ; new scrolling margins
- and dspstate,not dspdecom ; clear remembered origin mode
- test vtemu.vtflgop,decom ; was origin mode active?
- jz atsasd3 ; z = no
- or dspstate,dspdecom ; remember origin mode was active
- atsasd3:or vtemu.vtflgop,decom ; set origin mode
- push cursor ; get current main display cursor
- pop dspcmain ; save it
- mov dx,dspcstat ; get status line cursor
- mov dh,mar_top ; set row
- jmp atsetcur ; set cursor
-
- atsasd4:test dspstate,dsptype ; was previous display = status line?
- jnz atsasd5 ; nz = yes
- ret ; else do nothing
- atsasd5:push dspmsave ; restore scrolling margins
- pop word ptr mar_top
- and vtemu.vtflgop,not decom ; clear origin mode bit
- test dspstate,dspdecom ; was origin mode on for main screen?
- jz atsasd6 ; z = no
- or vtemu.vtflgop,decom ; set it now
- atsasd6:push cursor ; get status line cursor position
- pop dspcstat ; save it
- mov dx,dspcmain ; get saved cursor position
- mov dspstate,0 ; say now doing main screen
- jmp atsetcur ; set cursor
- atsasd endp
-
- atssdt proc near ; Select Status Line Type, DECSSDT
- cmp inter,'$' ; correct intermediate char?
- je atssdt1 ; e = yes
- cmp ninter,0 ; no intermediates?
- jne atssdt0 ; ne = no
- call fproduct ; do PRODUCT macro
- atssdt0:ret
- atssdt1:test dspstate,dsptype ; on mode line already?
- jnz atssdt4 ; nz = yes, cannot reselect now
- cmp param,0 ; turn off status line?
- jne atssdt2 ; ne = no
- push dx ; save cursor position
- call fclrmod ; clear the line
- pop dx
- or yflags,modoff ; now say it's off
- mov flags.modflg,1 ; say mode line is owned by us
- ret
- atssdt2:cmp param,1 ; regular status line?
- jne atssdt3
- push dx
- call fmodlin ; turn on regular mode line
- pop dx
- and yflags,not modoff ; and say it's on
- mov flags.modflg,1 ; say mode line is owned by us
- ret
- atssdt3:cmp param,2 ; host writable?
- jne atssdt4 ; ne = no
- mov flags.modflg,2 ; say mode line is owned by host
- atssdt4:ret
- atssdt endp
-
- ; VT52 compatibility mode routines.
-
- ; Return to ANSI mode.
-
- v52ans: or vtemu.vtflgop,decanm ; turn on ANSI flag
- mov ax,oldterm ; terminal type at startup
- cmp ax,ttvt52 ; was VT52 the prev kind?
- jne v52ans1 ; ne = no
- mov ax,ttvt320 ; use VT320
- v52ans1:mov oldterm,ax
- mov flags.vtflg,ax ; restore it
- call chrdef ; set default char sets
- call atsc ; save cursor status
- test yflags,modoff ; mode line supposed to be off?
- jnz v52ans2 ; nz = yes
- call fmodlin ; rewrite mode line
- v52ans2:ret
-
- ; VT52 cursor positioning.
-
- v52pos: mov ttstate,offset v52pc1 ; next state
- ret
- v52pc1: sub al,' '-1 ; minus offset
- xor ah,ah
- mov param,ax ; stash it here
- mov ttstate,offset v52pc2 ; next state
- ret
- v52pc2: sub al,' '-1 ; minus offset
- xor ah,ah
- mov param+2,ax ; stash here
- mov ttstate,offset atnrm ; reset state to "normal"
- jmp atcup ; position and return
-
- ; VT52 print controls
-
- v52ps: mov param,0 ; print screen
- mov lparam,0
- jmp ansprt ; simulate ESC [ 0 i
- v52pl: mov param,1 ; print line
- jmp short v52pcom ; simulate ESC [ ? 1 i
- v52pcb: mov param,5 ; Enter printer controller on
- jmp short v52pcom ; simulate ESC [ ? 5 i
- v52pce: mov param,4 ; Exit printer controller on
- ; jmp short v52pcom ; simulate ESC [ ? 4 i
- v52pcom:mov lparam,'?' ; simulate ESC [ ? <number> i
- jmp ansprt ; process command
-
- v52sgm: mov setptr,offset G0set ; enter/exit special graphics mode
- cmp al,'F' ; enter VT52 graphics mode?
- jne v52sgm1 ; ne = no, exit and return to ASCII
- jmp mkdecspec ; 'G' make DEC special graphics in G0
- v52sgm1:jmp mkascii ; make ASCII in G0
-
- ; Heath-19 special functions
-
- h19sans:or vtemu.vtflgop,decanm ; Turn on ANSI flag. ESC <
- jmp chrdef ; set default char sets
- ; clear screen and go home
-
- h19ed: cmp param,0 ; Erase cursor to end of screen?
- jne h19ed2 ; ne = no
- mov ax,dx ; start at cursor
- mov bx,low_rgt ; lower right corner
- cmp bh,dh ; on status line?
- jae h19ed1 ; ae = no
- mov bh,dh ; put end on status line
- h19ed1: call vtsclr ; clear it
- ret
- h19ed2: cmp param,1 ; erase start of display to cursor?
- je h19esos ; e = yes
- cmp param,2 ; erase entire screen?
- je h19clrs ; e = yes
- ret ; else ignore
-
- ; erase entire screen
- h19clrs:cmp dh,byte ptr low_rgt+1 ; on status line?
- ja h19erl ; a = yes, do just erase in line
- xor dx,dx ; go to upper left corner
- call atsetcur ; do it
- xor ax,ax ; clear screen from (0,0)
- mov bx,low_rgt ; to lower right corner
- call vtsclr ; clear it
- ret
-
- h19erl: xor al,al ; erase whole line
- mov bl,byte ptr low_rgt ; physical width
- jmp erinline ; erase whole line, cursor stays put
-
- h19ero: xor al,al ; erase start of line to cursor
- mov bl,dl
- jmp erinline ; clear that part of line
-
- ; erase start of screen to cursor
- h19esos:cmp dh,byte ptr low_rgt+1 ; on status line?
- ja h19ero ; a = yes, do just erase in line
- jmp ersos ; do regular erase start of screen
-
- h19wrap:or vtemu.vtflgop,decawm ; turn on line wrapping
- ret
- h19nowrp:and vtemu.vtflgop,not decawm ; turn off line wrapping
- ret
-
- h19herv:mov ah,curattr ; get current cursor attribute
- mov cl,extattr
- call setrev ; ESC p set reversed video
- mov curattr,ah ; store new attribute byte
- ret
-
- h19hxrv:mov ah,curattr ; get current cursor attribute
- mov cl,extattr
- call clrrev ; ESC q set normal video
- mov curattr,ah ; store new attribute byte
- ret
-
- h19sc: mov dx,cursor
- mov h19cur,dx ; save cursor position
- ret
-
- h19rc: mov dx,h19cur ; saved cursor position
- jmp atsetcur ; set cursor and return
-
- ; Heath-19 set mode "ESC x "
- h19smod:mov ttstate,offset hsmod ; setup to parse rest of seq
- ret
- hsmod: mov modeset,1 ; say set mode
- mov ttstate,offset atnrm
- sub al,'0' ; remove ascii bias
- jmp htrsm1 ; perform mode set
-
- h19cmod:mov ttstate,offset hcmod ; setup to parse rest of seq
- ret
-
- hcmod: mov modeset,0 ; say reset mode
- mov ttstate,offset atnrm
- sub al,'0' ; remove ascii bias
- jmp htrsm1 ; perform mode reset
-
- hrcup: mov al,escape ; send "ESC Y row col" cursor report
- call prtbout ; send with no local echo
- mov al,'Y'
- call prtbout
- mov al,byte ptr cursor+1 ; get row
- add al,' ' ; add ascii bias
-
- call prtbout ; send it
- mov al,byte ptr cursor ; get column
- add al,' ' ; add ascii bias
- call prtbout ; and send it too
- ret
-
- ; Insert/Delete characters and lines
- inslin proc near
- mov ax,param ; insert line
- or ax,ax ; any args?
- jne insli1 ; ne = yes
- inc ax ; insert one line
- insli1: mov scroll,al ; lines to scroll
- mov dx,cursor ; current position
- cmp dh,mar_bot ; below bottom margin?
- ja insli3 ; a = below bottom margin
- push word ptr mar_top
- mov mar_top,dh ; call present position the top
- call atscrd ; scroll down
- pop word ptr mar_top ; restore margins
- xor dl,dl ; go to left margin
- jmp atsetcur ; reposition cursor and return
- insli3: ret
- inslin endp
-
- dellin proc near
- mov ax,param ; delete line(s)
- or ax,ax ; any args?
- jne delli1 ; ne = yes
- inc ax ; insert one line
- delli1: mov scroll,al ; line count
- mov dx,cursor ; where we are presently
- cmp dh,mar_bot ; at or below bottom margin?
- jae delli3 ; ae = yes, do not scroll
- push word ptr mar_top ; save current scrolling margins
- mov mar_top,dh ; temp top margin is here
- call atscru ; scroll up
- pop word ptr mar_top ; restore scrolling margins
- jmp atsetcur ; restore cursor
- delli3: ret
- dellin endp
-
- ansich proc near ; ANSI insert characters ESC [ Pn @
- mov cx,param
- or cx,cx ; any arguments?
- jne ansic1 ; ne = no, ignore
- inc cx ; use one
- ansic1: push bx ; use this as insert/delete flag
- mov bh,1 ; do an insert operation
- ansic2: call insdel ; do common insert/delete code
- pop bx
- ret
- ansich endp
-
- inschr proc near ; insert open (space) char at cursor
- push bx ; use this as insert/delete flag
- mov bh,1 ; do an insert operation
- mov cx,1 ; do one character
- call insdel ; do common insert/delete code
- pop bx
- ret
- inschr endp
-
- atdelc proc near
- mov cx,param ; Delete characters(s)
- or cx,cx ; zero becomes one operation
- jnz atdelc1
- inc cx ; delete one char. Heath ESC N
- atdelc1:push bx ; use this as insert/delete flag
- mov bh,-1 ; do a delete operation
- atdelc2:call insdel ; do common insert/delete code
- pop bx
- ret
- atdelc endp
-
- ; Common code for insert/delete char
- insdel proc near ; BH has insert/delete code
- mov dx,cursor ; logical cursor
- cmp decrlm,0 ; host writing direction active?
- je insdel11 ; e = no
- call hldirection
- insdel11:
- cmp thisline,0 ; is line already single width?
- je insdel1 ; e = yes
- add dl,dl ; double the cursor column
- add cx,cx ; double repeat count
- test flags.vtflg,ttd463+ttd470 ; D463/D470?
- jz insdel1 ; z = no
- shl mar_right,1 ; this one doubles the margins
- insdel1:mov bl,mar_right
- inc bl ; number of screen columns
- sub bl,dl ; width - cursor
- cmp cl,bl ; skipping more than screen width?
- jbe insdel2 ; be = no
- mov cl,bl ; limit to screen width please
- insdel2:
- ; dh=logical cursor row, dl= logical cursor column, cx has repeat count
- ; bl = logical screen width - 1, bh = +1 for insert, -1 for delete chars.
- mov bl,cl ; offset
- xor ch,ch
- or bh,bh ; ins or del?
- jl insdel5 ; l = delete
- ; Insert processor
- mov cl,mar_right ; right margin
- sub cl,dl ; minus cursor location
- mov dl,mar_right ; start at right margin
- insdel4:push cx
- push dx
- sub dl,bl ; back up by offset
- call hldirection
- call getatch ; read char from vscreen
- pop dx
- push dx
- call hldirection
- call qsetatch ; write it farther to the right
- pop dx
- pop cx
- dec dl ; backup one column
- loop insdel4
- jmp short insdel7
- ; Delete processor
- insdel5:mov cl,mar_right ; right margin
- sub cl,dl ; minus starting position
- sub cl,bl ; minus displacement (num deletes)
- inc cl ; count column 0
- or cl,cl
- jle insdel7
- insdel6:push cx
- push dx
- add dl,bl ; look to right
- call hldirection
- call getatch ; read char from vscreen
- pop dx
- push dx
- call hldirection
- call qsetatch ; write it farther to the left
- pop dx
- pop cx
- inc dl ; next column
- loop insdel6
-
- insdel7:mov cl,bl ; fill count
- xor ch,ch
- jcxz insdel9 ; z = empty
- mov ah,scbattr ; get fill
- mov al,' '
- insdel8:push cx
- xor cl,cl ; extended attributes
- push dx
- call hldirection
- call qsetatch ; write new char
- pop dx
- inc dl ; next column
- pop cx
- loop insdel8
-
- insdel9:mov dx,cursor ; logical cursor again
- cmp thisline,0 ; is line already single width?
- je insde10 ; e = yes
- add dl,dl ; move to double char cell
- test flags.vtflg,ttd463+ttd470 ; D463/D470?
- jz insde10 ; z = no
- shr mar_right,1 ; this one doubles the margins
- insde10:call atsetcur ; set it to current char
- mov dl,dh ; rows to update
- call touchup
- mov dx,cursor ; in case we are called indirectly
- ret
- insdel endp
-
- noins: mov insmod,0 ; turn off insert mode
- ret
-
- entins: mov insmod,0ffh ; enter insert mode
- ret
-
- ; Line type to/from single or double
- linesgl proc near ; convert line to single width char
- push ax
- push bx
- push cx
- push dx
- mov bx,dx ; cursor
- mov bl,bh
- xor bh,bh ; bx now holds row
- cmp linetype [bx],0 ; is line already single width?
- je linsglx ; e = yes
- mov linetype [bx],0 ; say will be single now
- mov dh,byte ptr cursor+1 ; row
- xor dl,dl ; start in column 0
- mov cl,mar_right ; number of columns on screen - 1
- inc cl
- shr cl,1 ; number of columns to do
- xor ch,ch
- push cx ; save around loop below
- linsgl1:push cx ; save loop counter
- push dx
- shl dl,1 ; double column number
- call direction ; set dx to desired position
- call getatch ; read char (al) and attribute (ah)
- pop dx ; logical attribute to cl
- push dx
- call direction ; set dx to desired position
- call qsetatch ; write char (al) and attribute (ah)
- pop dx ; and logical attribute is in cl
- inc dl ; next column
- pop cx
- loop linsgl1
- pop cx ; recover column counter
- mov dl,cl
- linsgl2:push cx ; save counter
- push dx
- call direction ; set dx to desired position
- mov ah,scbattr ; screen background
- xor cl,cl ; extended attribute
- mov al,' '
- call qsetatch ; write char
- pop dx
- pop cx
- inc dl ; next column
- loop linsgl2 ; repeat for all characters
- mov dl,dh ; rows to touchup
- call touchup
- linsglx:pop dx
- pop cx
- pop bx
- pop ax
- jmp atscur ; update cursor and return
- linesgl endp
-
- linedbl proc near ; convert line to double width char
- push ax ; must reset physical cursor
- push bx ; to same char as before expansion
- push cx ; but does not modify variable cursor
- push dx
- mov bx,dx ; cursor
- mov bl,bh
- xor bh,bh ; bx now holds row
- cmp linetype [bx],0 ; is line single width?
- jne lindblx ; ne = no. nothing to do
- mov linetype [bx],1 ; say will be double width now
- mov cl,mar_right ; number of columns on the screen - 1
- inc cl
- xor ch,ch
- shr cl,1 ; number of items to do
- mov dl,cl
- dec dl
- lindbl1:push cx ; save loop counter
- push dx
- call direction ; set dx to desired position
- call getatch ; read char (al) and attribute (ah)
- pop dx ; extended attribute is in cl
- shl dl,1 ; double the column number
- push dx
- call direction ; set dx to desired position
- call qsetatch ; write char and attribute
- pop dx
- inc dl ; move to second column of double
- push dx
- call direction ; set dx to desired position
- mov al,' ' ; space as filler
- call qsetatch ; write that char
- pop dx
- dec dl
- shr dl,1
- dec dl
- pop cx
- loop lindbl1
- mov dl,dh ; rows to touchup
- call touchup
- lindblx:pop dx
- pop cx
- pop bx
- pop ax
- jmp atscur ; update the cursor and return
- linedbl endp
-
- ; Printer support routines
- ansprt proc near
- mov di,offset ansprt0 ; routine to process arguments
- call atreps ; repeat for all parms
- ret
-
- ansprt0:mov ax,param[si] ; pick up the argument
- or ax,ax ; 0 (print all/part of screen)?
- jnz ansprt1 ; nz = no
- cmp ninter,0 ; unwanted intermediates?
- jne anspr4a ; ne = got one, illegal here
- call fpntchk ; check printer
- call pntext ; do whole screen or scrolling extent
- jmp atsetcur ; reposition cursor and return
-
- ansprt1:cmp ax,1 ; 1 (print current line)?
- jne ansprt4 ; ne = no
- call fpntchk ; check for printer ready
- call pntlin ; print current line
- mov al,LF
- call fpntchr
- call fpntflsh ; flush printer buffer
- jmp atsetcur ; reposition cursor and return
-
- ansprt4:cmp ax,4 ; 4 (auto print disable)?
- jne ansprt5 ; ne = no
- cmp lparam,'?' ; was it ESC [ ? 4 i
- jne anspr4a ; ne = no, so it was ESC [ 4 i
- test anspflg,vtautop ; check state of print flag
- jz anspr4a ; z = off already
- or anspflg,vtautop ; say auto-print enabled to toggle off
- call ftrnprs ; toggle mode line PRN indicator
- anspr4a:ret
-
- ansprt5:cmp ax,5 ; 5 (auto print enable)?
- jne ansprtx ; ne = no
- call fpntchk ; check printer, ignore carry ret
- cmp lparam,'?' ; was it ESC [ ? 5 i
- jne anspr5a ; ne = no
- test anspflg,vtautop ; is print already enabled?
- jnz ansprtx ; nz = yes, leave trnprs intact
- and anspflg,not vtautop ; say auto-print disabled to toggle on
- call ftrnprs ; toggle on mode line PRN indicator
- ret
- anspr5a:test anspflg,vtcntp ; controller print already enabled?
- jnz ansprtx ; nz = yes
- and anspflg,not vtautop ; clear single-char flag for toggling
- or anspflg,vtcntp ; controller print enabled
- mov emubufc,0 ; clear string buffer
- mov ttstate,offset ansmc ; do transparent print
- call ftrnprs ; toggle on mode line PRN indicator
- ansprtx:ret
- ansprt endp
-
- ; State machine active while Media Copy On (Print Controller ON). Copies all
- ; chars to the printer until and excluding Media Copy Off (ESC [ 4 i) or a
- ; repeated Media Copy On (ESC [ 5 i) has been received or the emulator reset.
- ; New char is in al.
- ansmc proc near
- mov ttstate,offset ansmc ; stay in this state
- cmp al,escape ; start a new sequence?
- je ansmc1 ; e = yes
- cmp al,CSI ; start a new sequence?
- je ansmc0a ; e = yes
- mov emubufc,0 ; say no matched chars
- call fpntchr ; print char in al, ignore errors
- ret
- ; CSI seen
- ansmc0a:call ansmc5 ; playback previous matches
- call atpclr ; clear parser
- mov pardone,offset ansmc4 ; where to go when done
- mov parfail,offset ansmc5 ; where to go when fail, playback
- mov ttstate,offset ansmc3 ; get numeric arg
- mov emubuf,CSI ; stuff CSI
- mov emubufc,1
- ret
- ; Escape seen
- ansmc1: call ansmc5 ; playback previous matches
- mov ttstate,offset ansmc2 ; get left square bracket
- mov emubufc,1 ; one char matched
- mov emubuf,al ; store it
- ret
-
- ansmc2: cmp al,'[' ; left square bracket?
- je ansmc2a ; e = yes
- call ansmc5 ; playback previous matches
- call fpntchr ; print char in al, ignore errors
- ret
-
- ansmc2a:inc emubufc ; say matched "ESC ["
- mov emubuf+1,al ; store left square brace
- call atpclr ; clear parser
- mov pardone,offset ansmc4 ; where to go when done
- mov parfail,offset ansmc5 ; where to go when fail, playback
- mov ttstate,offset ansmc3 ; get numeric arg
- ret
- ; CSI or ESC [ seen
- ansmc3: inc emubufc ; another char
- mov bx,emubufc ; qty stored
- mov emubuf[bx-1],al ; store it
- mov ah,al ; check for C0 and C1 controls
- and ah,not 80h
- cmp ah,20h ; control range?
- jb ansmc5 ; b = yes, mismatch, playback
- jmp atparse ; parse control sequence
- ; parse succeeded, al has Final char
- ansmc4: cmp al,'i' ; correct Final char?
- jne ansmc5 ; ne = no, playback previous matches
- cmp lparam,0 ; missing letter parameter?
- jne ansmc5 ; ne = no, mismatch
- cmp ninter,0 ; missing intermediates?
- jne ansmc5 ; ne = no, mismatch
- mov cx,nparam ; number of parameters
- xor bx,bx ; subscript
- ansmc4a:mov ax,param[bx]
- add bx,2 ; next param
- cmp ax,4 ; CSI 4 i MC OFF?
- je ansmc4b ; e = yes, stop printing
- loop ansmc4a ; keep trying all parameters
- jmp short ansmc7 ; forget this one, start over
-
- ; Media OFF found
- ansmc4b:mov ttstate,offset atnrm ; return to normal state
- call fpntflsh ; flush printer buffer
- test anspflg,vtcntp ; was printing active?
- jz ansmc7 ; z = no
- and anspflg,not vtcntp ; yes, disable print controller
- call ftrnprs ; toggle mode line PRN indicator
- ret
- ; playback emubufc matched chars
- ansmc5: mov cx,emubufc ; matched char count
- jcxz ansmc7 ; z = none
- push ax ; save current char in al
- push si
- mov si,offset emubuf ; matched sequence, cx chars worth
- cld
- ansmc6: lodsb ; get a char
- call fpntchr ; print it, ignore errors
- loop ansmc6 ; do all matched chars
- pop si
- pop ax
- mov emubufc,cx ; clear this counter
- ansmc7: mov ttstate,offset ansmc ; reset state to the beginning
- ret
- ansmc endp
-
- dgprt proc near ; RS F ? <char> DG Print routines
- mov ttstate,offset dgprt1 ; get the <char>
- ret
- dgprt1: mov ttstate,offset atnrm ; reset state
- cmp al,0 ; Simulprint off?
- jne dgprt2 ; ne = no
- mov al,7 ; reform to be VT autoprint off
-
- dgprt2: cmp al,1 ; Simulprint on?
- jne dgprt3 ; ne = no
- mov al,8 ; reform to be VT autoprint on
-
- dgprt3: cmp al,3 ; Print Pass Through on?
- jne dgprt4 ; ne = no
- dgprt3a: ; RS F ` alternative to RS F ? 3
- test anspflg,vtcntp ; controller print already enabled?
- jnz dgprt7 ; nz = yes
- and anspflg,not vtautop ; clear single-char flag for toggling
- or anspflg,vtcntp ; controller print enabled
- mov emubufc,0 ; clear string buffer
- mov ttstate,offset dgmc ; do transparent print
- call ftrnprs ; toggle on mode line PRN indicator
- ret
-
- dgprt4: cmp al,8 ; VT-style autoprint on?
- jne dgprt5 ; ne = no
- call fpntchk ; check printer, ignore carry ret
- test anspflg,vtautop ; is print already enabled?
- jnz dgprt7 ; nz = yes, leave trnprs intact
- and anspflg,not vtautop ; say auto-print disabled to toggle on
- call ftrnprs ; toggle on mode line PRN indicator
- ret
-
- dgprt5: cmp al,7 ; VT-style autoprint off?
- jne dgprt6 ; ne = no
- test anspflg,vtautop ; check state of print flag
- jz dgprt7 ; z = off already
- or anspflg,vtautop ; say auto-print enabled to toggle off
- call ftrnprs ; toggle mode line PRN indicator
- ret
-
- dgprt6: cmp al,':' ; Print Screen?
- jne dgprt7 ; ne = no
- mov ah,mar_bot ; save margins
- mov al,mar_top
- push ax
- mov mar_top,0 ; set to full screen height
- mov al,byte ptr low_rgt+1 ; bottom text row
- mov mar_bot,al
- push cursor
- xor dx,dx ; cursor to home
- call dgprtwn ; print this window
- pop cursor
- pop ax
- mov mar_top,al ; restore margins
- mov mar_bot,ah
- dgprt7: ret
- dgprt endp
-
- dgppb proc near ; RS F x <n> Printer Pass back to host
- mov bx,offset dgppb1 ; call back routine
- jmp get1n ; setup consume one <n>
- dgppb1: mov al,dgescape ; send RS R x 0 cannot set
- call prtbout ; out, no echo
- mov al,'R'
- call prtbout
- mov al,'x'
- call prtbout
- mov al,'0' ; say cannot set NRC printer mode
- call prtbout
- ret
- dgppb endp
-
- ; State machine active while DG Simulprint is On. Copies all chars to the
- ; printer until and excluding Simulprint Off (RS F ? 0) has been received
- ; or the emulator reset.
- ; New char is in al.
- dgmc proc near
- mov ttstate,offset dgmc ; stay in this state
- cmp al,dgescape ; start a new sequence?
- je dgmc1 ; e = yes
- mov emubufc,0 ; say no matched chars
- call fpntchr ; print char in al, ignore errors
- ret
- ; RS seen
- dgmc1: call ansmc5 ; playback previous matches
- mov ttstate,offset dgmc2 ; get next char
- mov emubufc,1 ; one char matched
- mov emubuf,al ; store it
- ret
-
- dgmc2: cmp al,'F' ; 'F' part of RS F ? 2
- jne dgmc7 ; ne = no
- inc emubufc ; say matched "RS F"
- mov emubuf+1,al ; store it
- mov ttstate,offset dgmc3 ; get query char
- ret
- ; RS F seen
- dgmc3: cmp al,'?' ; 'F' part of RS F ? 2
- jne dgmc4 ; ne = no
- inc emubufc ; say matched "RS F ?"
- mov emubuf+1,al ; store it
- mov ttstate,offset dgmc5 ; get final char
- ret
-
- dgmc4: cmp al,'a' ; RS F a alternative?
- jne dgmc7 ; ne = no
- jmp short dgmc8 ; finish up
-
- dgmc5: cmp al,'2' ; RS F ? seen, correct final char?
- je dgmc8 ; e = yes
-
- dgmc7: call ansmc5 ; playback previous matches
- call fpntchr ; print char in al, ignore errors
- mov ttstate,offset dgmc ; start over
- ret
-
- dgmc8: mov ttstate,offset atnrm ; return to normal state
- call fpntflsh ; flush printer buffer
- test anspflg,vtcntp ; was printing active?
- jz dgmc9 ; z = no
- and anspflg,not vtcntp ; yes, disable print controller
- mov al,6 ; send Control-F to host
- call prtbout ; output, no echo
- call ftrnprs ; toggle mode line PRN indicator
- dgmc9: ret
- dgmc endp
-
- pntlin proc near ; print whole line given by dx
- push ax
- push bx
- push cx
- push dx
- xor ch,ch
- mov cl,mar_right ; number of columns - 1
- mov dl,cl ; Bios column counter, dh = row
- inc cl ; actual line length, count it down
- test vtemu.vtflgop,vswdir ; writing right to left?
- jnz pntlin2 ; nz = yes, do not trim spaces
- cmp decrlm,0 ; host writing direction active?
- jne pntlin2 ; ne = yes
- pntlin1:push cx
- call getatch ; read char (al) and attribute (ah)
- pop cx ; and extended bit pair to cl
- cmp al,' ' ; is this a space?
- jne pntlin2 ; no, we have the end of the line
- dec dl ; else move left one column
- loop pntlin1 ; and keep looking for non-space
-
- pntlin2:jcxz pntlin4 ; z = empty line
- xor dl,dl ; start in column 0, do cl chars
- pntlin3:push cx
- call getatch ; read char (al) and attribute (ah)
- pop cx
- inc dl ; inc to next column
- call fpntchr ; print the char (in al)
- jc pntlin5 ; c = printer error
- loop pntlin3 ; do cx columns
- pntlin4:mov al,cr ; add trailing cr for printer
- call fpntchr
- pntlin5:pop dx
- pop cx
- pop bx
- pop ax
- ret ; C bit controlled by pntchr
- pntlin endp
-
- pntext proc near ; print an extent of lines, depending
- push ax ; on flag bit vtextp
- push bx
- push dx
- xor dx,dx ; assume starting at top left
- mov bx,low_rgt ; and extending to lower right
- test anspflg,vtextp ; full screen wanted?
- jnz pntext1 ; nz = yes, else scrolling region
- mov dh,mar_top ; top of scrolling region
- mov bh,mar_bot ; bottom of scrolling region
- pntext1:call pntlin ; print a line
- jc pntext2 ; c = printer error
- mov al,LF
- call fpntchr
- jc pntext2
- inc dh
- cmp dh,bh ; done all requested lines?
- jbe pntext1 ; be = not yet, do another
- test anspflg,vtffp ; form feed needed at end?
- jz pntext2 ; z = no
- mov al,ff
- call fpntchr ; print the form feed char
- pntext2:pop dx
- pop bx
- pop ax
- ret
- pntext endp
-
- ; Set cursor coordinate DL (row) with consideration for writing direction.
- ; Active only under local writing direction control
- direction proc near
- test vtemu.vtflgop,vswdir ; writing left to right?
- jz direct1 ; z = yes, no changes needed
- sub dl,mar_right ; right margin column number
- neg dl ; make a positive value again
- direct1:ret
- direction endp
-
- ; Like direction, but functions if host writing direction decrlm is active
- ; as well as local control
- hldirection proc near
- cmp decrlm,0 ; host mode inactive?
- jne hldirect1 ; ne = no, obey
- test vtemu.vtflgop,vswdir ; writing left to right?
- jz hldirect2 ; z = yes, no changes needed
- hldirect1:sub dl,mar_right ; right margin column number
- neg dl ; make a positive value again
- hldirect2:ret
- hldirection endp
-
- ; Erase from cursor (DX, inclusive) to end of screen
- ; sense double width/height
- ereos proc near
- mov ax,dx ; erase from cursor to end of screen
- or dx,dx ; cursor at home position?
- jnz ereos1 ; nz = no
- ; e = yes, roll screen before clear
- push word ptr mar_top
- mov al,byte ptr low_rgt+1 ; bottom row number
- mov mar_bot,al
- mov mar_top,dh ; row of cursor
- inc al ; number of lines to scroll
- mov scroll,al
- call atscru ; scroll them up before erasure
- pop word ptr mar_top
- ; removes double w/h lines too
- xor ax,ax ; erase from here (home)
- mov bx,low_rgt ; bh = bottom row number
- call vtsclr ; clear screen
- ret
- ereos1: push dx ; save dx
- mov bl,dh ; get row number
- xor bh,bh
- cmp linetype [bx],0 ; single width line?
- je ereos2 ; e = yes
- shl dl,1 ; physical column is twice logical
- ereos2: or dl,dl ; starting at left margin?
- je ereos3 ; e = yes, this goes to single width
- inc bl ; else start on next line
- ereos3: cmp bl,byte ptr low_rgt+1 ; at the end of the screen?
- ja ereos4 ; a = yes, stop singling-up
- mov byte ptr linetype [bx],0 ; set to single width
- inc bx
- jmp short ereos3 ; loop, reset lines to end of screen
- ereos4: mov ax,dx ; cursor
- pop dx
- mov bx,low_rgt ; erase from cursor to end of screen
- call vtsclr ; clear it
- ret
- ereos endp
-
- ; Erase from start of screen to cursor (inclusive), sense double width/height
- ersos proc near
- xor ax,ax ; erase from start of screen
- ; to cursor, inclusive
- xor bx,bx ; start at top row (0)
- ersos1: cmp bl,dh ; check rows from the top down
- jae ersos2 ; ae = at or below current line
- mov byte ptr linetype [bx],0; set line to single width
- inc bx ; inc row
- jmp short ersos1 ; look at next line
- ersos2: or dl,dl ; at left margin of current line?
- jne ersos3 ; ne = no, leave line width intact
- mov byte ptr linetype [bx],0 ; convert to single width
- ersos3: mov bl,dh ; get row number
- xor bh,bh
- cmp linetype [bx],0 ; single width line?
- je ersos4 ; e = yes
- shl dl,1 ; physical column is twice logical
- ersos4: mov bx,dx ; cursor position to bx
- call vtsclr ; clear it
- ret
- ersos endp
-
- ; Erase in line, from column AL to column BL, in row DH
- erinline proc near
- mov ah,dh ; set row
- mov bh,dh
- push bx
- mov bl,dh ; get row
- xor bh,bh
- cmp linetype [bx],0 ; single width line?
- pop bx ; pop does not affect flags
- je erinli1 ; e = yes
- shl al,1
- shl bl,1 ; physical column is twice logical
- erinli1:cmp bl,byte ptr low_rgt ; wider than the physical screen?
- jb erinli2 ; b = no, not wider than screen
- mov bl,byte ptr low_rgt ; physical width
- erinli2:cmp al,byte ptr low_rgt
- jb erinli3
- mov al,byte ptr low_rgt
- erinli3:call vtsclr ; clear it
- ret
- erinline endp
-
- ; General erasure command which skips over protected chars.
- ; Preset margins and cursor to obtain all three erasure kinds.
- erprot proc near ; erase cursor to end of region
- mov cursor,dx ; preserve cursor
- erprot1:push dx
- call direction
- call getatch ; read a char, get attributes
- pop dx
- cmp protectena,0 ; is protected mode enabled?
- je erprot4 ; e = no, erase all
- test cl,att_protect ; protected mode?
- jnz erprot2 ; nz = yes, retain it
- erprot4:xor cl,cl ; clear extended attributes
- mov ah,scbattr ; background attributes
- mov al,' '
- push dx
- call direction
- call qsetatch ; quietly update char
- pop dx
- erprot2:inc dl ; next column
- cmp dl,mar_right ; did right margin?
- jbe erprot1 ; be = no
- mov dl,mar_left ; rest to left margin
- inc dh ; next line down
- cmp dh,mar_bot ; did the last row?
- jbe erprot1 ; be = no
- erprot3:mov dl,byte ptr cursor+1 ; starting line, dh is ending line
- mov dh,mar_bot
- call touchup ; repaint part of screen
- mov dx,cursor
- ret
- erprot endp
-
- ; Clear screen from AX to BX, where AH = row, AL = column, ditto for BX.
- ; This routine accomodates right to left writing. BX >= AX.
- vtsclr proc near
- test vtemu.vtflgop,vswdir ; writing left to right?
- jz vtsclr4 ; z = yes
- cmp bh,ah ; same row?
- je vtsclr2 ; e = yes
- push ax ; multiple lines
- push bx ; save both coordinates
- mov bl,mar_right
- mov bh,ah ; pick just top line
- call vtsclr2 ; delete fraction of top line
- pop bx ; recover ending position
- push bx
- inc ah ; omit top row, now done
- dec bh ; omit last line, could be fractional
- cmp bh,ah ; any whole lines remaining to delete?
- jb vtsclr1 ; b = no, finish up
- mov bl,mar_right ; get right most physical column
- xor al,al ; to end of line (on left)
- call atsclr ; clear top line and whole remainders
- vtsclr1:pop bx ; setup for last line to be cleared
- push bx ; get last row again
- xor al,al ; start at logical left margin
- jmp short vtsclr3 ; ax and bx are already pushed
-
- vtsclr2:push ax ; erase single line, whole or part
- push bx
- vtsclr3:mov ah,mar_right ; borrow reg ah (same as bh)
- sub ah,bl ; reflect right to left
- mov bl,ah
- or bl,bl ; overflow?
- jns vtsclr5 ; ns = no, is ok
- xor bl,bl ; limit to logical screen
- vtsclr5:mov ah,mar_right
- sub ah,al
- mov al,ah
- jns vtsclr6
- mov al,mar_right ; limit to logical screen
- vtsclr6:mov ah,bh ; restore ah
- xchg al,bl ; reverse to get physical ax < bx
- call atsclr ; erase part/all of single line
- pop bx
- pop ax
- ret
- ; for writing left to right
- vtsclr4:jmp atsclr ; do normal erasure and return
- vtsclr endp
-
- ; routines supporting scrolling and double width/height chars
- ; scroll has number of lines to scroll
- atscru proc near ; scroll screen up one line
- push ax ; assumes dx holds cursor position
- push bx ; returns with dx = old row, new col
- push cx
- push si
- xor bh,bh
- mov bl,mar_top ; top line to move
- xor ch,ch
- mov cl,scroll ; number of lines to move
- mov al,mar_bot ; bottom line to scroll
- sub al,bl ; number of lines minus 1
- inc al ; number of lines
- cmp al,cl ; scrolling region smaller than scroll?
- jge atscru1 ; ge = no, is ok
- mov scroll,al ; limit to region
- cmp al,1 ; at least one line to scroll?
- jge atscru1 ; ge = yes
- mov scroll,1 ; no, force one
- atscru1:mov al,scroll
- mov ah,byte ptr low_rgt+1 ; last text line on screen
- inc ah ; number of screen lines
- cmp al,ah ; exceeds number of lines on screen?
- jbe atscru8 ; be = scrolling not more than that
- mov al,ah ; limit to screen length
- mov scroll,al
- atscru8:xor ah,ah
- mov si,ax ; scroll interval
- mov bl,mar_top
- mov cl,mar_bot
- sub cl,bl
- inc cl ; number of lines in region
- sub cl,scroll ; cx = those needing movement
- cmp cl,0
- jle atscru3
- atscru2:mov al,linetype[bx+si] ; get old type
- mov linetype[bx],al ; copy to new higher position
- mov al,linescroll[bx+si] ; get horizontal scroll value
- mov linescroll[bx],al ; copy too
- inc bx
- loop atscru2
- atscru3:mov bl,mar_bot ; set fresh lines to single attribute
- mov cl,scroll ; number of fresh lines (qty scrolled)
- xor ch,ch
- atscru4:mov linetype[bx],0
- mov linescroll[bx],0
- dec bx
- loop atscru4 ; clear old bottom lines
- mov bl,dh ; get row of cursor
- xor bh,bh
- cmp linetype[bx],0 ; single width?
- je atscru5 ; e = yes
- shr dl,1 ; reindex to single width columns
- atscru5:pop si
- pop cx
- pop bx
- pop ax
- test anspflg,vtcntp ; controller print active?
- jz atscru6 ; z = no, ok to change screen
- ret ; else keep screen intact
- atscru6:jmp vtscru ; call & ret the msy scroll routine
- atscru endp
-
- atscrd proc near ; scroll screen down scroll lines
- push ax ; assumes dx holds cursor position
- push bx ; returns with dx = old row, new col
- push cx
- push si
- xor ch,ch
- mov cl,scroll ; number of lines to scroll
- xor bh,bh
- mov bl,mar_bot ; bottom line to move
- mov al,bl
- xor ah,ah
- sub al,mar_top ; number of lines minus 1
- inc al ; number of lines
- cmp al,cl ; scrolling region smaller than scroll?
- jge atscrd1 ; ge = no, is ok
- mov scroll,al ; limit to region
- cmp al,1 ; at least one line to scroll?
- jge atscrd1 ; ge = yes
- mov scroll,1 ; no, force one
- atscrd1:mov al,scroll
- mov si,ax ; si = scroll
- mov bl,dh ; get row of cursor
- xor bh,bh ; make into an index
- sub bl,scroll ; si + this bx will be new bottom line
- mov cl,bl
- sub cl,mar_top
- inc cl
- cmp cl,0
- jle atscrd3
- atscrd2:mov al,linetype[bx] ; get old line's type
- mov linetype[bx+si],al ; copy to new lower position
- mov al,linescroll[bx] ; get per line horizontal scroll
- mov linescroll[bx+si],al ; copy too
- dec bx
- loop atscrd2
- atscrd3:mov bl,mar_top ; start with this line
- xor bh,bh
- mov cl,scroll ; number of lines scrolled
- xor ch,ch
- atscrd4:mov linetype[bx],0 ; clear new top lines
- mov linescroll[bx],0
- inc bx
- loop atscrd4
- mov bl,dh ; get row of cursor
- xor bh,bh
- cmp linetype[bx],0 ; single width?
- je atscrd5 ; e = yes
- shr dl,1 ; reindex to single width columns
- atscrd5:pop si
- pop cx
- pop bx
- pop ax
- test anspflg,vtcntp ; controller print active?
- jz atscrd6 ; z = no, ok to change screen
- ret ; else keep screen intact
- atscrd6:jmp vtscrd ; call & ret the msy scroll routine
- atscrd endp
-
- ; Returns carry set if column in DL is a tab stop, else carry clear.
- ; Enter with column number in DL (starts at column 0, max of swidth-1)
- ; and tabstop buffer offset in SI.
- istabs proc near
- push bx
- push cx
- mov cl,dl ; column number (0 to swidth-1)
- and cl,00000111b ; keep bit in byte (0-7)
- inc cl ; map to 1-8
- mov bl,dl ; column
- shr bl,1 ; bl / 8 to get byte
- shr bl,1
- shr bl,1
- xor bh,bh ; clear high byte
- mov bl,[si+bx] ; get a byte of tab bits
- ror bl,cl ; rotate to put tab-set bit into carry
- pop cx
- pop bx
- ret
- istabs endp
-
- ; Modify (set/clear) a tabstop. Enter with DL holding column (0 to swidth-1)
- ; Set a tabstop into buffer pointed at by SI.
- tabset proc near
- mov modeset,1 ; set a tabstop
- jmp short modtabs
- tabset endp
-
- ; Clear a tabstop
- tabclr proc near
- mov modeset,0 ; clear a tabstop
- jmp short modtabs
- tabclr endp
-
- ; Worker for set/clear tabstop, si has pointer to tabstops array
- modtabs:push bx
- push cx
- mov cl,dl ; column number (0 to swidth-1)
- and cl,00000111b ; keep bit in byte (0-7)
- mov ch,1 ; tab bit to change
- shl ch,cl ; shift to bit-in-byte position
- mov bl,dl ; column
- shr bl,1 ; bl / 8 to get byte
- shr bl,1
- shr bl,1
- xor bh,bh ; clear high byte
- mov cl,[si+bx] ; get byte of tabs bits
- not ch ; invert bit marker to create hole
- and cl,ch ; clear the tab bit
- not ch ; recover setting pattern
- cmp modeset,0 ; clear the tab bit?
- jz modtab1 ; z = yes
- or cl,ch ; set the tab bit
- modtab1:mov [si+bx],cl ; store tab byte
- pop cx
- pop bx
- ret
-
- ; This routine initializes the VT setups at startup. It is called from
- ; procedure lclyini in module msyibm.
- vsinit proc near
- mov vtemu.vtflgst,vsdefaults ; Init to defaults in mssdef.h
- mov vtemu.vtflgop,vsdefaults ; Init runtime state to setup items
- mov savflgs,vsdefaults
- mov iniflgs,vsdefaults
- mov insmod,0 ; turn off insert mode
- xor dl,dl ; Column 1 has no tab stop
- mov si,vtemu.vttbs ; from the cold-start buffer
- call tabclr ; clear that tabstop
- push es
- push ds
- pop es
- cld
- mov al,1 ; set tabs at columns 9, spaced by 8
- mov cx,(swidth-1)/8 ; bytes to do, at 8 bits/byte
- mov di,offset deftabs+1 ; starting byte for column 9 (1...)
- rep stosb
- xor al,al ; get a zero
- mov cx,slen ; clear linetype array
- mov di,offset linetype
- rep stosb
- mov cx,slen
- mov di,offset linescroll ; clear horiz scroll per line
- rep stosb
- pop es
- mov vtemu.vttbst,offset tabs ; addrs of active tabs for STATUS
- mov vtemu.vttbs,offset deftabs ; addrs of tabs for setup (SET)
- call cpytabs ; copy default to active
- mov vtemu.att_ptr,offset att_normal ; ptr to video attributes
- mov ah,byte ptr low_rgt ; right most column (counted from 0)
- sub ah,8 ; place marker 9 columns from margin
- mov belcol,ah ; store column number to ring bell
- ret
- vsinit endp
-
- ; Initialization routine.
- ; Enter with dl = index for baud rate table
- ; dh = parity in bits 4-7, number of data bits in bits 0-3
- ansini proc near
- mov ax,vtemu.vtflgst ; setup flags
- mov vtemu.vtflgop,ax
- mov iniflgs,ax
- mov savflgs,ax
- mov ax,flags.vtflg ; get current terminal type
- cmp ax,tttek ; non-text?
- je ansin3 ; e = yes
- mov oldterm,ax ; remember it here for soft restarts
- ansin3: mov anspflg,0 ; clear printing flag
- mov al,byte ptr low_rgt ; right most column (counted from 0)
- sub al,8 ; place marker 9 columns from margin
- mov belcol,al ; store column number to ring bell
- cmp dl,lbaudtab ; out of range index?
- jb ansin1 ; b = no, store it
- mov dl,lbaudtab-2 ; yes, make it the maximum (128)
- ansin1: mov baudidx,dl ; save baud rate index
- mov al,dh ; get parity/number of databits
- and al,0FH ; isolate number of databits
- mov datbits,al ; save
- mov cl,4
- shr dh,cl ; isolate parity code
- cmp dh,lpartab ; out of range code?
- jb ansin2 ; b = no, store it
- mov dh,lpartab-1 ; make it the maximum
- ansin2: mov parcode,dh ; save
- mov cx,low_rgt
- mov oldscrn,cx ; remember old screen dimensions
- jmp atreset ; reset everything
- ansini endp
-
- atxreset proc near ; Reset via host command
- cmp nparam,0 ; need no Parameters, no Intermediates
- jne atxres1 ; ne = not a reset
- cmp ninter,0 ; any intermediates?
- je atreset ; e = none, it is a reset
- atxres1:ret ; ignore command
- atxreset endp
-
- atreset proc near ; Reset-everything routine
- test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jnz atres9
- test tekflg,tek_sg ; special graphics active?
- jz atres9 ; z = no
- call tekend ; exit special graphics
- atres9: mov ax,apcstring ; seg of apcmacro memory area
- or ax,ax ; empty?
- jz atres10 ; z = yes
- mov es,ax
- mov ah,freemem
- int dos ; free that memory
- atres10:mov apcstring,0
- mov bracecount,0 ; APC-macro worker variables
- mov cursor,0 ; cursor is at 0,0
- mov havesaved,0 ; unmark saved cursor section
- mov al,1 ; assume underline cursor
- test vtemu.vtflgst,vscursor ; kind of cursor in setup
- jnz atres0 ; nz = underline
- inc al ; else say block
- atres0: mov atctype,al ; VTxxx cursor type
- mov h19cur,0 ; Heath-19 saved cursor
- mov dspstate,0 ; saved modeline state
- call udkclear ; clear User Definable Key contents
- push vtemu.vtflgst ; setup flags
- pop vtemu.vtflgop ; operational flags
- mov decrlm,0 ; host writing direction to left-right
- and vtemu.vtflgop,not vscntl ; assume no 8-bit controls
- mov ax,oldterm ; get terminal at entry time
- or ax,ax ; inited yet? (initing Tek too)
- jnz atres0a ; nz = yes
- mov ax,ttvt320 ; pretend initing VT320
- jmp short atres0b
- atres0a:mov flags.vtflg,ax ; use it again
- atres0b:test ax,ttvt102+ttvt100+tthoney+ttpt200 ; VT100 class?
- jnz atres1 ; nz = yes, turn on ansi mode
- test ax,ttvt320+ttvt220 ; VT320/VT220?
- jz atres1a ; z = no, no ansi, no 8-bit controls
- test vtemu.vtflgst,vscntl ; want 8-bit controls?
- jz atres1 ; z = no
- or vtemu.vtflgop,vscntl ; turn on 8-bit controls
- atres1: or vtemu.vtflgop,decanm ; turn on ANSI mode
- atres1a:mov mar_top,0 ; reset scrolling region
- mov ax,low_rgt ; virtual screen lower right corner
- mov mar_bot,ah ; logical bottom of screen
- test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jz atres1d ; z = no
- mov al,79 ; trim to 80 col screen
- atres1d:mov mar_right,al ; logical right edge of screen
- mov mar_left,0 ; DG left/right margins
- mov old8bit,-1 ; flags.remflg d8bit status, clear
- xor al,al ; ax is top/bottom margin
- mov dgwindow,ax ; init to first window to full screen
- mov dgwindcnt,1 ; DG window count, 1 = full screen
- mov cx,25
- xor bx,bx
- atres1i:mov dgwindcomp[bx],al ; set lines to uncompressed
- inc bx
- loop atres1i
- xor ax,ax
- mov savdgmar,ax ; clear DG saved margins
- mov protectena,al ; disable protected fields
- mov blinkdis,al ; disable blink disable
- mov dgroll,1 ; DG roll enabled
- mov dgaltid,ax ; DG alternate model id, clear it
- mov dghscrdis,al ; DG horz scroll disable is disabled
- mov cx,16
- xor bx,bx
- atres1e:mov dgcursave[bx],ax ; clear DG cursor named save area
- add bx,2
- loop atres1e
- mov cx,slen/2
- xor bx,bx
- atres1f:mov word ptr linescroll[bx],ax ; clear DG per line horiz scroll
- add bx,2
- loop atres1f
- mov dgnum,ax ; DG worker word, to be safe
- call dgcrossoff ; DG turn off crosshair
- mov dgcross,al ; DG crosshair activity, off
- mov dglinepat,0ffffh ; DG line pattern, default all dots
- mov dgcaller,offset atign ; DG default callback, ignorance
- mov numdigits,al ; more DG stuff
- mov param[0],ax ; setup call to atleds
- xor si,si
- call atleds ; clear the LED indicators
- call cpytabs ; initialize tab stops
- test flags.vtflg,ttvt320+ttvt220+ttvt102+ttvt100+tthoney+ttd463+ttd470
- jz atres1c ; z = no
- mov al,vtemu.vtchset ; setup char set
- cmp al,1 ; in range for NRCs?
- jb atres1c ; b = no
- cmp al,13 ; highest NRC ident?
- ja atres1c ; a = not NRC
- or vtemu.vtflgop,vsnrcm ; set NRC flag bit to activate NRCs
- atres1c:mov vtemu.vtchop,al ; remember char set
- call chrdef ; set default character sets
- call vtbell ; ring bell like VT100
- cmp flags.modflg,2 ; mode line owned by host?
- jne atres1h ; ne = no
- mov flags.modflg,1 ; say now owned by us
- atres1h:xor ax,ax ; not exiting connect mode, 80 col
- test vtemu.vtflgst,deccol ; need 132 columns?
- jz atres1g ; z = no, use 80 columns
- inc al ; say set 132 column mode
- atres1g:call chgdsp ; call Change Display proc in msy
- and vtemu.vtflgop,not deccol; assume mode is reset (80 cols)
- cmp byte ptr low_rgt,79 ; is screen narrow now?
- jbe atres2 ; be = yes
- or vtemu.vtflgop,deccol ; set the status bit
-
- ; ATRES2 used in 80/132 col resetting
- ATRES2: mov cx,slen ; typically 24 but do max lines
- xor di,di
- xor al,al
- atres3: mov linetype[di],al ; clear the linetype array to single
- mov linescroll[di],al ; horizontal scroll per line
- inc di
- loop atres3
- mov ah,att_normal ; get present normal coloring
- test vtemu.vtflgop,vsscreen ; want reverse video?
- jz atres4 ; z = no
- call revideo ; reverse them
- atres4: mov scbattr,ah ; set background attributes
- mov curattr,ah ; and cursor attributes
- mov extattr,0 ; no reverse video, no underline
- mov dx,cursor ; get cursor
- call atsetcur ; set cursor
- call atsctyp ; set right cursor type
- xor ax,ax ; starting location
- mov bx,low_rgt ; ending location
- call vtsclr ; clear the whole screen
- cmp flags.modflg,1 ; mode line on and owned by us?
- jne atres5 ; ne = no, leave it alone
- test yflags,modoff ; mode line supposed to be off?
- jnz atres5 ; nz = yes
- push dx
- call fmodlin ; write normal mode line
- pop dx
- atres5: test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jz atres6 ; z = no
- or vtemu.vtflgop,decawm ; Autowrap active
- or vtemu.vtflgst,decawm ; Autowrap active
- atres6: call atpclr ; clear parser work area
- xor ax,ax
- mov parstate,ax ; reset parser
- mov emubufc,ax ; clear work buffer
- mov atwrap,al ; clear wrap flag
- mov SSptr,ax ; clear single shift flag
- mov insmod,al ; reset insert mode
- mov h19stat,al ; clear heath extended status byte
- mov h19ctyp,1 ; Heath-19 cursor to underline
- mov anspflg,al ; clear printer flag
- call atsc ; save cursor information
- jmp atnorm ; set normal state
- atreset endp
-
- ; Re-initialization routine. Called when Term was called but screen was
- ; restored from a previously saved screen, etc.
- ansrei proc near
- mov dx,cursor
- call atsctyp ; set cursor type [rbv]
- mov ax,vtemu.vtflgst ; setup
- or ax,vtemu.vtflgop ; operational
- test ax,deccol ; want 80 columns?
- jnz ansre2 ; nz = no
- cmp byte ptr low_rgt,79 ; want 80 cols. Is active screen wider?
- jbe ansre2 ; be = no
- mov byte ptr low_rgt,79 ; narrow down to 80 columns
- and vtemu.vtflgop,not deccol
- ansre2: jmp stblmds ; check settable modes, set flags
- ansrei endp
-
- ; This routine checks to see whether any of the settable modes have changed
- ; (things that can be changed in both SETUP and by host commands), and
- ; changes those that need to be changed. TMPFLAGS has the new VT100 setup
- ; flags, VTFLAGS has the old. This routine also updates VTFLAGS.
- ; Revised to allow MSY to reset scbattr when not in connect mode,
- ; to do "soft reset" if terminal type has changed, and to do a screen clear
- ; reset if the actual screen colors have changed.
-
- stblmds proc near
- mov ax,flags.vtflg ; get current terminal type
- cmp ax,tttek ; non-text?
- je stblm10 ; e = yes
- cmp ax,oldterm ; same as before?
- je stblm10 ; e = yes, skip over soft reset
- mov oldterm,ax ; remember current terminal type
- mov insmod,0 ; reset insert mode flag
- and iniflgs,not vsnrcm ; turn off NRC bit from last time
- mov mar_top,0 ; reset top scrolling margin
- mov al,byte ptr low_rgt+1 ; and scrolling margin
- mov mar_bot,al ; to last normal line on screen
- mov ah,byte ptr low_rgt ; right most column (counted from 0)
- sub ah,8 ; place marker 9 columns from margin
- mov belcol,ah ; store column number to ring bell
- push es
- push ds
- pop es
- xor al,al ; get a zero
- mov di,offset linetype ; line type to single width chars
- mov cx,slen ; screen length
- cld
- rep stosb ; clear
- mov di,offset linescroll ; line horizontal scroll to none
- mov cx,slen
- rep stosb
- pop es
- and vtemu.vtflgop,not decanm
- test flags.vtflg,ttvt320+ttvt220+ttvt102+ttvt100+tthoney+ttpt200
- jz stblm10 ; z = no, not ansi class
- or vtemu.vtflgop,decanm ; set ansi flag bit
-
- stblm10:test flags.vtflg,ttd463+ttd470 ; D463/D470?
- jz stblm10a ; z = no
- mov cx,24 ; emulation screen lines
- xor al,al
- xor bx,bx
- stblm10b:or al,dgwindcomp[bx] ; is any line compressed (!= 0)?
- inc bx ; if so remember as non-zero
- loop stblm10b
- or al,al ; found any compressed lines?
- jz stblm10e ; z = no
- test vtemu.vtflgop,vscompress ; allowed to use graphics for it?
- jnz stblm10d ; nz = no, use 132 column text mode
- test tekflg,tek_active+tek_sg ; special graphics mode active?
- jnz stblm10e ; nz = yes
- stblm10c:call dgsettek ; setup special graphics mode
- jmp short stblm10e
- stblm10d:mov al,3 ; prep call on atrsm6, 132/80 col
- mov modeset,1 ; say want 132 columns
- call atrsm6 ; common worker
- cmp byte ptr low_rgt,79
- jbe stblm10c ; did not work, use graphics anyway
- stblm10e:mov al,flags.remflg ; get 7/8 bit configuration
- and al,d8bit ; select the control bit
- cmp old8bit,al ; changed?
- je stblm10a ; e = no
- mov old8bit,al ; save new state
- mov vtemu.vtchop,-1 ; force change below
- stblm10a:mov al,vtemu.vtchset ; setup character set
- cmp al,vtemu.vtchop ; operational character set
- je stblm3 ; e = same, no changes needed
- mov vtemu.vtchop,al ; remember this set
- and vtemu.vtflgop,not vsnrcm ; clear NRC active bit
- and vtemu.vtflgst,not vsnrcm
- cmp al,1 ; in range for NRC?
- jb stblm11 ; b = no
- cmp al,13 ; above NRCs?
- ja stblm11 ; a = yes
- or vtemu.vtflgop,vsnrcm ; set NRC active bit
- or vtemu.vtflgst,vsnrcm
- and vtemu.vtflgop,not vscntl ; no 8-bit controls
- stblm11:call chrdef ; init char sets
-
- stblm3: test vtemu.vtflgst,vswdir ; writing direction set?
- jz stblm3c ; z = no
- mov decrlm,0 ; yes, suppress host indicator
- stblm3c:mov ax,iniflgs ; flags at last entry
- xor ax,vtemu.vtflgst ; find which setup ones have changed
- test ax,deccol ; screen width?
- jz stblm3b ; z = no, don't touch it
- mov ax,vtemu.vtflgst ; Setup bits
- and ax,deccol ; select screen width
- and vtemu.vtflgop,not deccol ; clear operational flag bit
- or vtemu.vtflgop,ax ; set current width desired
- or al,ah ; collapse all bits
- mov modeset,al ; non-zero if 132 columns
- mov al,3 ; setup call to atrsm6
- call atrsm6 ; adjust display width
-
- stblm3b:cmp vtclear,1 ; screen need updating?
- mov vtclear,0 ; preserves cpu status bits
- jb stblm9 ; b = no
- ja stblm3a ; 2 or more means do a reset
- mov ah,att_normal ; 1, get new normal attributes setting
- mov scbattr,ah ; store new values
- mov curattr,ah
- jmp short stblm9
- stblm3a:mov cursor,0 ; reset cursor position
- jmp atres2 ; go to semi-reset
-
- ; check on screen normal/reversed
- stblm9: mov ax,iniflgs ; flags at last entry
- xor ax,vtemu.vtflgst ; find which setup ones have changed
- test ax,vsscreen ; screen background?
- jz stblm8 ; z = no, don't touch it
- test vtemu.vtflgop,vsscreen ; reverse video flag set?
- jnz stblm5 ; nz = yes, do it
- and vtemu.vtflgop,not vsscreen ; cleared (normal video)
- jmp short stblm6 ; reverse everything
- stblm5: or vtemu.vtflgop,vsscreen ; set (reverse video)
- stblm6: call atrss2 ; reverse screen and cursor attribute
- push es
- mov ax,seg data1
- mov es,ax
- mov ah,scbattr ; reset saved attribute also
- mov es:savecu+svattr_index,ah
- pop es
- stblm8: cmp flags.modflg,2 ; mode line enabled and owned by host?
- je stblm9a ; e = yes, leave it alone
- call fclrmod ; clear the mode line
- test yflags,modoff ; mode line supposed to be off?
- jnz stblm9a ; nz = yes
- call fmodlin ; write normal mode line
- and yflags,not modoff ; say modeline is not toggled off
- stblm9a:mov dx,cursor ; logical cursor
- push dx
- call direction ; set cursor for writing direction
- call setpos ; set the cursor physical position
- pop dx
- push vtemu.vtflgst
- pop iniflgs ; remember setup flags at this entry
- call frepaint
- ret
- stblmds endp
-
- ; Routine called when something is typed on the keyboard
-
- anskbi proc near
- mov ttkbi,0FFH ; just set a flag
- ret
- anskbi endp
-
-
- ; This routine copies the new tab stops when they have changed.
- ; Copies all 132 columns.
- cpytabs proc near
- mov cx,(swidth+7)/8 ; number of bytes in screen width
- jcxz cpytab1 ; z = none to do
- mov si,offset deftabs ; source is setup array
- mov di,offset tabs ; destination is active array
- push es ; save es
- push ds
- pop es ; set es to data segment
- cld
- rep movsb ; do the copy
- pop es ; recover es
- cpytab1:ret
- cpytabs endp
-
- ; Routine to toggle between text and Tek graphics modes. No arguments.
- ; Text terminal type remembered in byte OLDTERM.
- ans52t proc FAR
- mov ax,flags.vtflg
- cmp ax,tttek ; in Tek mode now?
- je ans52b ; e = yes, exit Tek mode
- test tekflg,tek_active ; doing Tek sub mode?
- jnz ans52b ; nz = yes
- test ax,ttd463+ttd470 ; DG 463/D470?
- jnz ans52e ; nz = yes, go into DG graphics mode
- test denyflg,tekxflg ; is Tek mode disabled?
- jnz ans52a ; nz = yes, disabled
- mov oldterm,ax ; save text terminal type here
- call atsc ; save cursor and associated data
- mov flags.vtflg,tttek ; set Tek mode
- mov tekflg,tek_tek ; not a sub mode
- call tekini ; init Tek to switch screens
- ans52a: call atnorm
- ret
-
- ans52b: call tekend ; exit Tek graphics mode
- mov ax,oldterm
- or ax,ax ; inited yet?
- jnz ans52c ; nz = yes
- mov ax,ttvt320 ; fall back for initing
- ans52c: mov flags.vtflg,ax ; say text terminal now
- test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jnz ans52f ; nz = yes, cursor is ok already
- call atrc ; restore cursor etc
- call atsc ; save cursor etc
- ans52f: mov tekflg,0 ; say not doing tek submode now
- mov al,atctype
- call atsctyp ; set correct cursor type
- test yflags,modoff ; is mode line off?
- jnz ans52d ; nz = yes
- push dx ; save cursor position
- call frepaint ; restore text screen
- call fmodlin ; write mode line
- pop dx
- ans52d: call atnorm
- ret
- ; DG D473 graphics mode entry
- ans52e: mov oldterm,ax ; save text terminal type here
- call dgsettek ; switch to DG graphics
- jmp short ans52d
- ans52t endp
-
- ; Honeywell VIP 3.1 i.d. string [FD]
- athoney proc near
- cmp flags.vtflg,tthoney ; Honeywell mode?
- jne athone3 ; ne = no, ignore
- mov ttyact,0 ; group for networks
- mov cx,VIPstrl ; length of string
- mov si,offset VIPstr ; ptr to string
- cld
- athone1:lodsb ; get a byte
- push cx ; save regs
- push si
- call prtbout ; print WITHOUT echo
- pop si
- pop cx
- cmp cx,1 ; last char?
- ja athone2 ; a = not yet
- mov ttyact,1 ; end of network grouping
- athone2:loop athone1 ; loop for all characters
- athone3:jmp atnorm
- athoney endp
-
- athoncls proc near ; Honeywell ESC accent screen clear
- cmp nparam,0 ; absence of parameters?
- jne athoncl1 ; ne = no, fail
- cmp ninter,0 ; any intermediates?
- jne athoncl2 ; ne = yes, not this item
- cmp flags.vtflg,tthoney ; doing Honeywell emulation?
- jne athoncl1 ; ne = no
- xor dx,dx ; move cursor to Home position
- call ereos ; erase to end of screen
- xor dx,dx
- jmp atsetcur ; set cursor and return
- athoncl1:ret
- athoncl2:jmp atdgnrc ; try Norwegian/Danish NRC designation
- athoncls endp
-
- ; Data General D463/D470 support routines
-
- ; Data General mode C0 control codes
- dgctrl proc near
- test anspflg,vtcntp ; printing desired?
- jz dgctrl1 ; z = no
- call fpntchr ; print char in al
- dgctrl1:and ax,001fh ; clear for word use below
- mov di,ax ; use AL as a word index
- shl di,1
- jmp dgc0[di] ; dispatch on DG C0 control codes
- dgctrl endp
-
- ; Consume ESC ... Final
- dgansi proc near
- mov ttstate,offset dgansi1 ; come here til end or break
- ret
- dgansi1:cmp al,20h ; control code?
- jb dgansi2 ; b = yes, break
- cmp al,'[' ; end of ANSI escape sequence part?
- je dgansi2 ; e = yes, get parms, intermediates
- cmp al,40h ; parameters, intermediates?
- jae dgansi3 ; ae = no, consider it to be a final
- dgansi2:ret ; else stay in this state
- dgansi3:jmp atnorm ; reset state to normal
- dgansi endp
-
- dgesc proc near ; Parse Data General RS commands
- mov dgnum,0 ; clear numerical result
- mov ttstate,offset dgesc1 ; set up to get next char
- ret
- dgesc1: mov bx,offset dgesctab ; dispatch table
- mov ttstate,offset atnrm ; reset state
- jmp atdispat ; dispatch on char in AL
- dgesc endp
-
- ; Parse RS F/G <letter><DGnumber>(repeated)
- ; F/G has been read, letter is next
- dgFSERIES:mov ttstate,offset Fdisp ; dispatcher for incoming RS F
- ret
- Fdisp: mov ttstate,offset atnrm ; normal state
- mov bx,offset fltable ; table of letters
- jmp atdispat ; dispatch to action routine
-
- dgGSERIES:mov ttstate,offset Gdisp ; dispatcher for incoming RS G
- ret
- Gdisp: mov ttstate,offset atnrm ; normal state
- mov bx,offset gltable ; table of letters
- jmp atdispat ; dispatch to action routine
-
- dgRSERIES:mov ttstate,offset Rdisp ; dispatcher for incoming RS R
- ret
- Rdisp: mov ttstate,offset atnrm ; normal state
- mov bx,offset rltable ; table of letters
- jmp atdispat ; dispatch to action routine
-
- ; DG <n>,<nn>,<nnn> processors. Enter with BX holding callback address.
- ; Returns number in dgnum and resets state to atnrm.
- ; get one DG numeric
- get1n: mov ttstate,offset getnum ; worker routine
- mov dgnum,0 ; clear numerical result
- mov numdigits,1 ; wanted qty of digits
- mov dgcaller,bx ; call back address
- ret
- ; get two DG hex digits
- get2n: mov ttstate,offset getnum ; worker routine
- mov dgnum,0 ; clear numerical result
- mov numdigits,2 ; wanted qty of digits
- mov dgcaller,bx ; call back address
- ret
- ; get three DG hex digits
- get3n: mov ttstate,offset getnum ; worker routine
- mov dgnum,0 ; clear numerical result
- mov numdigits,3 ; wanted qty of digits
- mov dgcaller,bx ; call back address
- ret
-
- get3loc:mov ttstate,offset getloc ; get three DG Location digits
- mov dgnum,0
- mov numdigits,3
- mov dgcaller,bx
- ret
-
- getloc proc near
- mov bl,numdigits ; number of digits remaining
- xor bh,bh
- or al,al ; is it truely null (RS L cmd stuff)?
- jz getloc3 ; z = yes, exit now
- and al,00011111b ; keep only five lower bits
- mov emubuf[bx],al ; save byte
- dec numdigits ; say one more digit done
- dec bx
- or bx,bx ; done all?
- jz getloc1 ; z = yes
- ret ; else stay in state getloc
- getloc1:mov cx,3 ; three digits
- getloc2:mov bx,cx
- mov al,emubuf[bx] ; stored in reverse order
- push cx
- mov bx,dgnum ; get current value
- mov cl,5
- shl bx,cl ; times 32
- add bl,al ; add current digit
- adc bh,0
- mov dgnum,bx ; keep result
- pop cx
- loop getloc2
- clc ; clear carry to say not null term
- jmp short getloc4
-
- getloc3:stc ; set carry to say ended on NULL
- getloc4:mov bx,dgcaller ; get callback address
- mov dgcaller,offset atign ; reset default DG callback processor
- mov ttstate,offset atnrm ; set normal state
- jmp bx ; go to callback address
- getloc endp
-
- ; Return binary number in dgnum. When done it resets state to atnrm,
- ; clears callback address. Note that this proc accepts ALL bytes and uses
- ; only the four lower bits, regardless of what the DG manuals suggest.
- getnum proc near
- and al,0fh ; keep lower four bits
- mov cl,4
- mov bx,dgnum ; get current value
- shl bx,cl ; times 16
- and al,0fh ; keep lower four bits
- add bl,al ; add current digit
- adc bh,0
- mov dgnum,bx ; keep result
- dec numdigits ; say one more digit done
- cmp numdigits,0 ; done all?
- jz getnum2 ; z = yes
- ret ; else stay in this state
- getnum2:mov bx,dgcaller ; get callback address
- mov dgcaller,offset atign ; reset default DG callback processor
- mov ttstate,offset atnrm ; set normal state
- jmp bx ; go to callback address
- getnum endp
-
- out2n proc near ; send <nn> report from value in AL
- push cx
- mov ch,al ; preserve a copy
- mov cl,4
- shr al,cl ; get high nibble
- and al,0fh
- add al,'0' ; ascii bias
- call prtbout
- mov al,ch ; recover copy
- and al,0fh ; get low nibble
- add al,'0'
- call prtbout
- pop cx
- ret
- out2n endp
-
- out2na proc near ; send <nn> report from value in AL
- push cx
- mov ch,al ; preserve a copy
- mov cl,4
- shr al,cl ; get high nibble
- and al,0fh
- add al,'@' ; ascii bias
- call prtbout
- mov al,ch ; recover copy
- and al,0fh ; get low nibble
- add al,'@'
- call prtbout
- pop cx
- ret
- out2na endp
-
- dgign1n proc near ; ignore a <n> command
- mov bx,offset atnorm ; ignore the <n>
- jmp get1n
- dgign1n endp
-
- dgign2n proc near ; ignore a <nn> command
- mov bx,offset atnorm ; ignore the <nn>
- jmp get2n
- dgign2n endp
-
- dgprtfm proc near ; Control-A DG print form
- mov cursor,dx ; save cursor location
- dgprtf1:mov dl,mar_right ; start at right margin
- mov cl,dl
- sub cl,mar_left ; minus left
- inc cl
- xor ch,ch ; number of columns to do
- dgprtf3:push cx
- call dgprta ; get char which would be printed
- pop cx
- cmp al,' ' ; space?
- jne dgprtf4 ; ne = no, end scan here
- dec dl ; scan backward another column
- loop dgprtf3
- dgprtf4:jcxz dgprtf6 ; z = empty line
- mov dl,mar_left ; start at left margin
- dgprtf5:push cx
- push dx
- call dgprta ; get printable
- call fpntchr ; print char in al
- pop dx
- pop cx
- jc dgprtf7 ; c = printer error
- inc dl
- loop dgprtf5 ; do count
-
- dgprtf6:mov al,CR ; line terminator for printer
- push dx
- call fpntchr
- pop dx
- jc dgprtf7 ; c = printer error
- mov al,LF
- push dx
- call fpntchr
- pop dx
- jc dgprtf7 ; c = printer error
- inc dh ; next row down
- cmp dh,mar_bot ; below window now?
- jbe dgprtf1 ; be = no
- dgprtf7:mov al,6 ; Control-F to host when done
- call prtbout ; output, no echo
- mov dx,cursor
- ret
- dgprtfm endp
-
- dgprta proc near ; worker, report printable char at dx
- call getatch ; read char (al) and attribute (ah)
- cmp protectena,0 ; protected mode enabled
- je dgprta1 ; e = no
- test cl,att_protect ; protected mode?
- jnz dgprta2 ; nz = yes, use a space
- ret ; else use as-is
- dgprta1:test ah,att_bold ; bold?
- jnz dgprta3 ; nz = yes, use as-is
- dgprta2:mov al,' ' ; replace with space
- dgprta3:ret
- dgprta endp
-
- dgprtwn proc near ; Control-Q DG print window
- mov cursor,dx ; save cursor location
- dgprtw1:mov dl,mar_right ; start at right margin
- mov cl,dl
- sub cl,mar_left
- inc cl
- xor ch,ch ; number of columns to do
- dgprtw3:push cx
- call dgprtb ; get char which would be printed
- pop cx
- cmp al,' ' ; space?
- jne dgprtw4 ; ne = no, end scan here
- dec dl ; scan backward another column
- loop dgprtw3
- dgprtw4:jcxz dgprtw6 ; z = empty line
- mov dl,mar_left ; start at left margin
- dgprtw5:push cx
- push dx
- call dgprtb ; get printable
- call fpntchr ; print char in al
- pop dx
- pop cx
- jc dgprtw7 ; c = printer error
- inc dl
- loop dgprtw5 ; do count
- dgprtw6:mov al,CR ; line terminator for printer
- push dx
- call fpntchr
- pop dx
- jc dgprtw7 ; c = printer error
- mov al,LF
- push dx
- call fpntchr
- pop dx
- jc dgprtw7 ; c = printer error
- inc dh ; next row down
- cmp dh,mar_bot ; below window now?
- jbe dgprtw1 ; be = no
- dgprtw7:mov al,6 ; Control-F to host when done
- call prtbout ; output, no echo
- mov dx,cursor
- ret
- dgprtwn endp
-
- dgprtb proc near ; worker to yield printable char
- call getatch ; read char (al) and attribute (ah)
- test al,80h ; high bit set?
- jnz dgprtb1 ; nz = yes, use a space
- cmp al,20h ; in printables?
- ja dgprtb2 ; a = yes
- dgprtb1:mov al,' ' ; replace with space
- dgprtb2:ret
- dgprtb endp
-
- dgrevidon:mov ah,curattr ; RS D Control-V reverse video on
- call setrev ; reverse video on
- mov curattr,ah ; store new attribute byte
- ret
-
- dgrevidoff:mov ah,curattr ; RS E Control-B reverse video off
- call clrrev ; 2, reverse video off
- mov curattr,ah ; store new attribute byte
- ret
-
- dgblkena:mov blinkdis,0 ; Control-C DG blink enable
- ret
- dgblkdis:mov blinkdis,1 ; Control-D DG blink disable
- ret
-
- dgblkon proc near ; Control-N DG Blink on
- cmp blinkdis,0 ; disabled?
- jne dgblkon1 ; ne = blink is disabled
- mov ah,curattr ; get current cursor attribute
- call setblink ; blink enable
- mov curattr,ah ; store new attribute byte
- dgblkon1:ret
- dgblkon endp
-
- dgblkoff proc near ; Control-O DG Blink off
- mov ah,curattr ; get current cursor attribute
- call clrblink ; blink disable
- mov curattr,ah ; store new attribute byte
- ret
- dgblkoff endp
-
- dgwinhome proc near ; Control-H DG window home
- mov dl,mar_left ; want to skip protected chars too
- mov dh,mar_top
- mov cursor,dx ; remember for protected checking
- jmp dgsetcur ; do protected mode positioning
- dgwinhome endp
-
- dguson proc near ; Control-T DG underscoring on
- mov ah,curattr ; get current cursor attribute
- call setunder
- mov curattr,ah ; store new attribute byte
- ret
- dguson endp
-
- dgusoff proc near ; Control-U DG underscoring off
- mov ah,curattr ; get current cursor attribute
- call clrunder
- mov curattr,ah ; store new attribute byte
- ret
- dgusoff endp
-
- dgdimon proc near ; Control-\ DG dim on
- mov ah,curattr ; get current cursor attribute
- call clrbold
- mov curattr,ah ; store new attribute byte
- ret
- dgdimon endp
-
- dgdimoff proc near ; Control-] DG dim off
- mov ah,curattr ; get current cursor attribute
- call setbold
- mov curattr,ah ; store new attribute byte
- ret
- dgdimoff endp
-
- dgsfc proc near ; RS A <color>, set foreground color
- mov ttstate,offset dgsfc1 ; state to get next char
- ret
- dgsfc1: mov ttstate,offset atnrm ; reset state
- test flags.vtflg,ttd463 ; D463?
- jz dgsfc2 ; z = no, D470
- mov ah,curattr ; current coloring
- test al,0fh ; setting to background?
- jnz dgsfc1a ; nz = no
- mov cl,4
- rol ah,cl ; get background coloring
- dgsfc1a:and ah,0fh ; keep foreground
- mov dg463fore,ah ; polygon foreground coloring
- ret
- dgsfc2: cmp al,100 ; select ACM mode?
- je dgsfc5 ; ne = no
- dgsfc3: and al,0fh ; keep lower 4 bits
- jz dgsfc4 ; z = black
- xor al,8 ; invert DG intensity bit
- jnz dgsfc4
- or al,8 ; pick up dark grey as second except'n
- dgsfc4: mov ah,curattr
- and ah,not 0Fh ; remove foreground
- or ah,al ; set new foreground
- mov ah,scbattr
- and ah,not 0Fh
- or ah,al
- mov curattr,ah ; save it
- mov scbattr,ah
- ret
- dgsfc5: mov ah,att_normal ; get normal background colors
- mov scbattr,ah
- mov curattr,ah ; set current to them
- dgsfcx: ret
- dgsfc endp
-
- dgsbc proc near ; RS B <color>, set background color
- mov ttstate,offset dgsbc1 ; state to get next char
- ret
- dgsbc1: mov ttstate,offset atnrm ; reset state
- test flags.vtflg,ttd463 ; D463?
- jnz dgsbcx ; nz = yes, ignore command
- cmp al,100 ; select ACM mode?
- je dgsbc2 ; e = yes
- and al,0fh ; mask out all but IBM PC background
- jz dgsbc3 ; z = black
- and al,7 ; remove IBM PC blinking bit
- mov cl,4
- shl al,cl ; move bits to high nibble
- dgsbc3: mov ah,curattr
- and ah,0fh ; remove background
- or ah,al ; set new background
- mov curattr,ah ; save it
- mov ah,scbattr
- and ah,0fh ; remove background
- or ah,al ; set new background
- mov scbattr,ah ; save it
- ret
- dgsbc2: mov ah,att_normal ; get normal background colors
- mov scbattr,ah ; set current to them
- mov curattr,ah ; set current to them
- dgsbcx: ret
- dgsbc endp
-
- dgeol proc near ; Control-K DG erase cursor to eol
- mov ax,dx ; cursor position
- mov bx,ax
- mov bl,mar_right ; end of line
- call atsclr ; erase from ax to bx
- ret
- dgeol endp
-
- dgeeos proc near ; RS F F DG erase cursor to end/scrn
- jmp erprot
- dgeeos endp
-
- dgescn proc near ; RS F E DG erase from 0,0 to eos
- xor dh,dh
- mov dl,mar_left ; left margin, top row
- call dggetmar ; get margins for this window
- call atsetcur ; set cursor
- mov ah,curattr
- call clrunder ; clear underline attribute
- call clrblink ; clear blink
- call setbold ; aka clear dim
- call clrrev ; clear reverse video attribute
- mov curattr,ah ; and cursor attributes
- mov extattr,0 ; clear extended attributes
- xor ax,ax ; erase from 0,0
- mov bh,byte ptr low_rgt+1 ; to end of screen
- mov bl,vswidth-1
- call atsclr ; clear screen
- ret
- dgescn endp
-
- dgewin proc near ; Control-L DG erase window
- mov ah,mar_top ; from top line of window
- mov bh,mar_bot ; to bottom line of window
- mov al,mar_left ; left margin
- mov bl,mar_right ; right margin
- cmp savdgmar,0 ; saved permanent margin?
- je dgewin1 ; e = no, mar_left/right are permanent
- mov al,byte ptr savdgmar ; use permanent l/r margins
- mov bl,byte ptr savdgmar+1
- dgewin1:call atsclr ; clear the area
- jmp dgwinhome ; do DG window home
- dgewin endp
-
- dgsleft proc near ; RS F C <nn> DG Scroll Left
- mov bx,offset dgslef1 ; get <nn>
- jmp get2n
- dgslef1:mov ax,dgnum ; qty columns to scroll
- jmp dglrworker ; do common worker
- dgsleft endp
-
- dgsright proc near ; RS F D <nn> DG Scroll Right
- mov bx,offset dgsrig1 ; get <nn>
- jmp get2n
- dgsrig1:mov ax,dgnum
- neg ax ; go right
- jmp dglrworker ; do common worker
- dgsright endp
-
- ; Worker to assist dgsleft/dgsright horizontal scroll. Enter with AX holding
- ; the additional scroll value, negative for scrolling left. Updates array
- ; linescroll.
- dglrworker proc near
- cmp dghscrdis,0 ; horiz scrolling disabled?
- je dglrwor1 ; e = no
- ret ; else ignore request
- dglrwor1:mov bl,mar_top ; do entire DG window
- xor bh,bh
- mov cl,mar_bot
- xor ch,ch
- sub cx,bx
- inc cx ; number of lines in the window
- cmp cl,byte ptr low_rgt+1 ; includes whole screen?
- jbe dglrwor2 ; be = no
- inc cx ; include status line
-
- dglrwor2:push cx
- mov cl,linescroll[bx] ; get horz scroll value
- xor ch,ch
- add cx,ax ; accumulate scroll
- jge dglrwor3 ; ge = non-negative
- xor cx,cx ; set to zero
- dglrwor3:cmp cx,127 ; max scroll
- jbe dglrwor4 ; be = in limits
- mov cl,127 ; set to max left
- dglrwor4:cmp linescroll[bx],cl ; any change?
- je dglrwor5 ; e = no
- mov linescroll[bx],cl ; set scroll
- push dx
- mov dl,bl
- mov dh,bl ; start/stop line numbers
- call touchup ; repaint just this line
- pop dx
- dglrwor5:inc bx ; next line
- pop cx
- loop dglrwor2
- ret
- dglrworker endp
-
- dginsl proc near ; RS F H DG Insert Line in window
- push dx ; save cursor
- mov param,0 ; set up ANSI call
- call inslin ; do insert line, can scroll
- pop dx ; recover cursor
- jmp atsetcur ; reset cursor
- dginsl endp
-
- dgdell proc near ; RS F I DG Delete Line in window
- mov scroll,1 ; line count
- push word ptr mar_top ; save current scrolling margins
- mov mar_top,dh ; temp top margin is here
- call atscru ; scroll up
- pop word ptr mar_top ; restore scrolling margins
- ret
- dgdell endp
-
- dgnarrow proc near ; RS F J DG select normal spacing
- mov cx,dgwindcnt ; number of windows
- xor bx,bx
- jcxz dgnarr3 ; z = none
- inc cx ; let implied last window be seen
- dgnarr1:cmp dh,byte ptr dgwindow[bx+1] ; look at window bottom edge
- jbe dgnarr3 ; be = cursor is in this window
- add bx,2 ; skip two margin bytes
- loop dgnarr1 ; next window
- dgnarr2:ret
-
- dgnarr3:mov cx,dgwindow[bx] ; get mar_top and mar_bot (ch)
- push cx ; save margins for touchup below
- mov bl,cl ; mar_top
- xor bh,bh
- sub ch,cl ; mar_bot - mar_top = lines in win -1
- xchg ch,cl
- xor ch,ch
- inc cx
- xor ax,ax ; zero and make ah a changed flag
- dgnarr4:xchg al,dgwindcomp[bx] ; set this window to normal width
- add ah,al ; remember if window line were wide
- xor al,al ; get zero again
- inc bx
- loop dgnarr4 ; do all lines in the window
- mov cl,byte ptr low_rgt+1 ; see if any screen lines are wide
- inc cl ; text lines
- xor ch,ch
- xor bx,bx
- xor al,al
- dgnarr5:cmp dgwindcomp[bx],0 ; count wide lines
- je dgnarr6 ; e = narrow
- inc al
- jmp short dgnarr7 ; one wide line is enough to count
- dgnarr6:inc bx
- loop dgnarr5
-
- dgnarr7:pop cx ; margins
- test tekflg,tek_active+tek_sg ; special graphics mode active?
- jz dgnarr8 ; z = no
- or ah,ah ; any line widths changed?
- jz dgnarr7a ; z = no
- push dx
- mov dx,cx ; cx = saved margins
- call touchup ; dl, dh are start stop rows
- pop dx
- dgnarr7a:ret
- dgnarr8:or al,al ; count of wide lines
- jz dgnarr9 ; z = all are narrow, go to 80 cols
- ret ; leave screen as-is with wide line(s)
- dgnarr9:mov al,3 ; prep call on atrsm6, 132/80 col
- mov modeset,0 ; say want 80 columns
- jmp atrsm6 ; common worker
- dgnarrow endp
-
- dgwide proc near ; RS F K DG select compressed spacing
- mov cx,dgwindcnt ; number of windows
- xor bx,bx
- jcxz dgwide3 ; z = none, means one as whole screen
- inc cx ; let implied last window be seen
- dgwide1:cmp dh,byte ptr dgwindow[bx+1] ; look at window bottom edge
- jbe dgwide3 ; be = cursor is in this window
- add bx,2 ; skip two margin bytes
- loop dgwide1 ; next window
- dgwide2:ret
-
- dgwide3:mov cx,dgwindow[bx] ; get mar_top and mar_bot (ch)
- push cx ; save them for touchup below
- mov bl,cl ; mar_top
- xor bh,bh
- sub ch,cl ; mar_bot - mar_top = lines in win -1
- xchg ch,cl
- xor ch,ch
- inc cx
- mov ax,1 ; al is set, ah is changed flag
- dgwide5:xchg al,dgwindcomp[bx] ; set this line to wide width
- dec al ; convert old 1 to a zero
- add ah,al ; accumulate changes
- mov al,1 ; get a 1 again
- inc bx
- loop dgwide5 ; do all lines in the window
- pop cx ; margins
- test vtemu.vtflgop,vscompress ; allowed to use graphics for it?
- jnz dgwide8 ; nz = no, use 132 column text mode
- test tekflg,tek_active+tek_sg ; special graphics mode active?
- jnz dgwide7 ; nz = yes
- dgwide6:push cx
- push dx
- call dgsettek ; setup special graphics mode
- pop dx
- pop cx
- ret
- dgwide7:or ah,ah ; any changes to width?
- jz dgwide7a ; z = no
- push dx
- mov dx,cx ; saved margins
- call touchup ; dl, dh are start stop rows
- pop dx
- dgwide7a:ret
- dgwide8:mov al,3 ; prep call on atrsm6, 132/80 col
- mov modeset,1 ; say want 132 columns
- call atrsm6 ; common worker
- cmp byte ptr low_rgt,79
- jbe dgwide6 ; did not work, use graphics anyway
- ret
- dgwide endp
-
- ; Toggle Normal/Compressed modes from the keyboard.
- dgnctoggle proc far
- mov dx,cursor ; get cursor
- mov bl,dh ; get row
- xor bh,bh
- cmp dgwindcomp[bx],0 ; normal mode?
- je dgnctog4 ; e = yes, do compressed
- call dgnarrow ; do normal
- ret
- dgnctog4:call dgwide ; do compressed
- ret
- dgnctoggle endp
-
- dgdelc proc near ; RS K DG Delete char
- mov param,0 ; set up ANSI call for one char
- jmp atdelc ; do delete
- dgdelc endp
-
- dgilbm proc near ; RS F [ Insert line between margins
- mov al,dghscrdis ; save horz scrolling disable flag
- push ax ; save til the end
- mov dghscrdis,1 ; disable horz scrolling for this cmd
- mov cursor,dx ; save this
- mov dl,mar_left ; start at the left side
- mov dh,mar_bot ; bottom of window
- or dh,dh ; row zero?
- jz dgilbm2 ; z = yes, just clear the line
-
- dgilbm1:dec dh ; up one row
- call getatch ; read a char
- inc dh ; go down a row
- call qsetatch ; write the char
- inc dl ; next column
- cmp dl,mar_right ; off end of row yet?
- jbe dgilbm1 ; be = no
- or dh,dh ; finished top row?
- jz dgilbm2 ; z = yes
- dec dh ; redo this one row up
- mov dl,mar_left ; reset to left window margin
- cmp dh,byte ptr cursor+1 ; finished cursor row yet?
- jae dgilbm1 ; ae = no
- dgilbm2:mov dx,cursor ; clear line cursor was on
- mov al,mar_left ; from left margin
- mov bl,mar_right ; to right window margin
- call erinline ; clear the window line
- mov dl,dh
- mov dh,mar_bot ; lines changed
- call touchup ; redisplay the new material
- mov dx,cursor
- pop ax ; recover horz scroll disable flag
- mov dghscrdis,al
- ret
- dgilbm endp
-
- dgdlbm proc near ; RS F \ Delete line between margins
- mov al,dghscrdis ; get horizontal scroll disable flag
- push ax ; save til the end
- mov dghscrdis,1 ; disable horz scrolling for this cmd
- mov cursor,dx ; save cursor position
- mov dl,mar_left ; start at the left side
- dgdlbm1:inc dh ; down one row
- call getatch ; read a char
- dec dh ; go up a row
- call qsetatch ; write the char
- inc dl ; next column
- cmp dl,mar_right ; off end of row yet?
- jbe dgdlbm1 ; be = no
- inc dh ; redo this one row down
- mov dl,mar_left ; reset to left window margin
- cmp dh,mar_bot ; finished bottom row yet
- jbe dgdlbm1 ; be = no
- mov dh,mar_bot ; clear last line in window
- mov al,mar_left
- mov bl,mar_right
- call erinline ; clear the window line
- pop ax ; recover horz scroll disable flag
- mov dghscrdis,al
- mov dx,cursor
- mov dl,dh ; region changed
- mov dh,mar_bot
- call touchup
- ret
- dgdlbm endp
-
- dgscs proc near ; RS F S <nn> DG Select Char Set
- mov bx,dgscs1 ; setup for <nn> value
- jmp get2n
- dgscs1: mov bx,dgnum ; get DG char set idents
- cmp bl,1fh ; last hard char set
- jbe dgscs2 ; be = in the hard sets
- mov bl,20h ; specify default soft set of trash
- dgscs2: or bl,bl ; use "keyboard language"?
- jnz dgscs3 ; nz = no
- mov bl,vtemu.vtchset ; get setup char set
- cmp bl,13 ; top of the NRCs
- jbe short dgscs4 ; as keyboard language
- xor bx,bx ; default to ASCII
- dgscs3: mov bl,dgchtab[bx] ; translate to Kermit idents
- dgscs4: cmp GLptr,offset G0set ; are we shifted out?
- jne dgscs5 ; ne = yes, presume G1set
- mov Gsetid,bl ; new set ident for G0
- jmp short dgscs6
- dgscs5: mov Gsetid+1,bl ; new set ident for G1
- dgscs6: mov bx,offset Gsetid ; pass list of sets to setup
- jmp chrsetup ; go make the new set
- dgscs endp
-
- dgalign proc near ; RS F > char DG fill screen with char
- mov ttstate,offset dgalig1 ; get char
- ret
- dgalig1:mov ttstate,offset atnrm ; reset state
- jmp atalig1 ; do DEC alignment work, char in AL
- dgalign endp
-
- dggrid proc near ; RS F 9 char DG fill screen with grid
- mov al,'#' ; set grid char in standard place
- jmp atalig1 ; do DEC alignment work, char in AL
- dggrid endp
-
-
- dgrolldis:mov dgroll,0 ; Control-S DG roll disable
- ret
-
- dgrollena:mov dgroll,1 ; Control-R DG roll enable
- ret
-
- dghsena:mov dghscrdis,0 ; RS F ^ DG horiz scroll enable
- mov dx,cursor
- jmp atsetcur ; set cursor to cause screen update
-
- dghsdis:mov dghscrdis,1 ; RS F ] DG horiz scroll disable
- ret
-
- dgpton: call setprot ; RS F L DG Protect on
- ret
-
- dgptoff:call clrprot ; RS F M DG Protect off
- ret
-
- protena:mov protectena,1 ; RS F V DG Protect enable
- ret ;
-
- protdis:mov protectena,0 ; RS F W DG Protect disable
- ret ;
-
- dg78bit proc near ; RS F U <n> DG Select 7/8 bit ops
- mov bx,dg78bit1 ; get <n>
- jmp get1n
- dg78bit1:cmp dgnum,1 ; 0 is 7 bit, 1 is 8 bit
- ja dg78bit3 ; a = illegal value, ignore
- je dg78bit2 ; e = 1
- and flags.remflg,not d8bit ; 7-bit, chop DG high bit
- ret
- dg78bit2:or flags.remflg,d8bit ; 8-bit
- dg78bit3:ret
- dg78bit endp
-
- dgdhdw proc near ; RS R E <n> DG Double high/wide
- mov bx,offset dgdhdw1
- jmp get1n ; set up for <n> arg
- dgdhdw1:mov ax,dgnum ; get <nn> result
- or ax,ax ; 2 and above are double highs
- jz dgdhdw2
- mov al,2 ; map double highs to 2
- jmp linedbl ; make line double width
- dgdhdw2:jmp linesgl ; make single width
- dgdhdw endp
-
- dgs25l proc ; RS F z <n> DG go to/set status line
- mov bx,offset dgs25l1 ; prep for <n> mode value
- jmp get1n
- dgs25l1:mov ax,dgnum ; get mode
- or ax,ax ; 0, 25th line is status?
- jnz dgs25l2 ; nz = no
- mov param,1 ; turn on regular mode line
- jmp atssdt1 ; do main worker
- dgs25l2:cmp al,3 ; blank the line?
- jne dgs25l3 ; ne = no
- jmp atssdt1 ; do main worker
- cmp al,2 ; use as ordinary text?
- jne dgs25l3 ; ne = no
- ret ; ignore this request
- dgs25l3:cmp al,1 ; get msg for line?
- je dgs25l4 ; e = yes
- ret
- dgs25l4:mov bx,offset dgs25l5 ; prep for <nn> text
- jmp get2n
- dgs25l5:mov dspcmain,dx ; save cursor in special area
- mov dspstate,dsptype ; say on status line
- mov al,mar_left
- mov ah,mar_right
- mov dspmsave,ax ; save margins
- mov mar_left,0 ; set left to screen left
- call fclrmod ; clear the line
- and yflags,not modoff ; say modeline is not toggled off
- mov flags.modflg,2 ; say mode line is owned by host
- mov dh,byte ptr low_rgt+1 ; bottom text line
- inc dh ; status line
- xor dl,dl ; absolute left margin
- call atsetcur ; set cursor
- cmp dgnum,0 ; chars of text
- je dgs25l7 ; e = yes
- mov ttstate,offset dgs25l6 ; come here for text
- ret
- dgs25l6:mov ttstate,offset atnrm ; reset state
- call atnrm ; write the character
- dec dgnum ; one less to do
- cmp dgnum,0 ; done?
- jle dgs25l7 ; le = yes
- ret ; stay on status line
- dgs25l7:mov dx,dspcmain ; restore cursor
- mov ax,dspmsave ; saved margins
- mov mar_left,al
- mov mar_right,ah
- mov dspstate,0 ; no longer on mode line
- jmp atsetcur ; set cursor
- dgs25l endp
-
- dgnscur proc near ; RS F } <n> <n> DG cursor named save
- mov bx,offset dgnscu1 ; get <n> memory cell (name, 0..15)
- jmp get1n
- dgnscu1:mov ax,dgnum ; get cell number
- mov word ptr emubuf,ax ; save here
- mov bx,offset dgnscu2 ; get <n> save (0) / restore (1)
- jmp get1n
- dgnscu2:mov bx,word ptr emubuf ; get named subscript
- mov ax,dgnum ; get op code
- cmp ax,1 ; save?
- jb dgnscu3 ; b = save
- ja dgnscu4 ; a = illegal, ignore
- mov al,dgctypesave[bx] ; get cursor size/type
- mov atctype,al ; active type
- call csrtype ; set it
- mov dx,dgcursave[bx] ; restore cursor position from storage
- mov cursor,dx ; remember for protected checking
- jmp dgsetcur ; set the cursor DG style
- dgnscu3:mov dgcursave[bx],dx ; save cursor
- mov al,atctype ; get cursor type
- mov dgctypesave[bx],al ; save
- dgnscu4:ret
- dgnscur endp
-
- dgsps proc near ; DG dual emulation set split screen
- mov ttstate,offset dgsps1 ; RS R A 0 <nn><n> or RS R A 1 <nn>
- ret
- dgsps1: mov bx,offset atnrm ; setup to ignore command
- cmp al,1 ; 0 or 1 expected
- ja dgsps3 ; a = illegal, ignore
- je dgsps2 ; e = case 1 <nn>
- jmp get3n ; case 0 <nn><n> as <nnn>
- dgsps2: jmp get2n
- dgsps3: ret
- dgsps endp
-
- dgdcs proc near ; RS F q <nn><nn> Dealloc Char Sets
- mov bx,offset dgdcs1 ; ignore for now
- jmp get2n
- dgdcs1: mov bx,offset atnrm
- jmp get2n
- dgdcs endp
-
- dgdefch proc near ; RS F R <char> 12<nn>'s Def Char
- mov ttstate,dgdefc1 ; get and discard char
- mov emubufc,0 ; set counter
- ret
- dgdefc1:inc emubufc ; count a <nn> pair
- cmp emubufc,12 ; done all?
- jae dgdefc2 ; ae = yes
- mov bx,offset dgdefc1 ; absorb 12 <nn> pairs
- jmp get2n
- dgdefc2:mov emubufc,0 ; clear counter
- jmp atnorm ; reset state
- dgdefch endp
-
- dgrchr proc near ; RS F d DG Read Chars Remaining
- mov al,dgescape ; response string
- call prtbout
- mov al,'o'
- call prtbout
- mov al,'9'
- call prtbout
- mov al,'0' ; high part of 10 bit count
- ;graphics mov al,'_'
- call prtbout
- mov al,'0' ; low part of 10 bit count
- ;graphics mov al,'_'
- call prtbout
- ret
- dgrchr endp
-
- dgresch proc near ; RS F e <n><n> DG Reserve Character
- mov bx,offset atnorm ; discard
- jmp get2n
- dgresch endp
-
- dgskl proc near ; RS F f <n> DG Set Kbd Language
- mov bx,offset dgskl1
- jmp get1n ; get parameter
- dgskl1: mov ax,dgnum ; 0=setup, 1=DG Int, 2=Latin1
- cmp ax,2 ; in range?
- ja dgskl4 ; a = no
- cmp ax,1 ; DG International?
- je dgskl2 ; e = yes
- ja dgskl3 ; a = no, Latin1
- mov al,vtemu.vtchset ; get setup char set
- mov dgkbl,al ; store keyboard language ident
- ret
- dgskl2: mov dgkbl,20 ; DG International
- ret
- dgskl3: mov dgkbl,16 ; Latin1
- dgskl4: ret
- dgskl endp
-
- dgsdo proc near ; RS R B <n><n><n> Set Device Options
- mov bx,offset dgsdo1 ; get first <n>
- jmp get1n
- dgsdo1: mov bx,offset atnrm ; get second and third <n>'s
- jmp get2n ; discard all
- dgsdo endp
-
- dgsfield:mov bx,offset dgsfie1 ; RS F C <ss><rr> Field attributes
- jmp get2n ; get first <nn>
- dgsfie1:mov bx,offset atnrm ; discard proc
- jmp get2n ; get second <nn>
-
- dgspage:mov bx,offset dgspag1 ; RS F D <ss><rr> Page attributes
- jmp get2n ; get first <nn>
- dgspag1:mov bx,offset atnrm ; discard proc
- jmp get2n ; get second <nn>
-
- dgsetw proc near ; RS F B <nn><n>.. Set windows
- mov dgwindcnt,0 ; count of windows entries
- mov emubuf+4,0 ; normal(0)/compressed (!0) flag
- dgsetw1:mov bx,offset dgsetw2 ; next processor
- jmp get2n ; get a <nn> window length
- dgsetw2:mov ax,dgnum
- mov word ptr emubuf,ax ; save around get1n work
- mov bx,offset dgsetw2a ; get <n> 0/1, compressed mode
- jmp get1n
- dgsetw2a:mov ax,dgnum
- mov emubuf+4,al ; save copy for just this window
- mov ax,word ptr emubuf ; <nn> length, 0 (end) to 24
- or ax,ax ; end of set indicator?
- jnz dgsetw2b ; nz = no
- mov ax,24 ; pseudo end
- dgsetw2b:xchg al,ah ; put row in ah
- mov bx,dgwindcnt ; get subscript
- cmp bx,24 ; too many windows? (24 == DG limit)
- ja dgsetw7 ; a = yes, else accept data
- inc bx
- mov dgwindcnt,bx ; update counter (1 == one window)
- dec bx
- shl bx,1 ; index words
- or bx,bx ; initial window?
- jnz dgsetw3 ; nz = no
- xor al,al ; start at 0,0
- jmp short dgsetw4
- dgsetw3:mov al,byte ptr dgwindow[bx-1] ; previous ending line
- inc al ; start this window down one line
- dgsetw4:add ah,al ; new mar_bot = new mar_top + skip
- dec ah ; count lines from zero
- cmp ah,byte ptr low_rgt+1 ; bottom of displayable screen?
- jb dgsetw5 ; b = no
- mov ah,byte ptr low_rgt+1 ; clamp to that bottom
- dgsetw5:mov dgwindow[bx],ax ; save [al=mar_top,ah=mar_bot] pair
- mov al,ah ; get current bottom
- mov ah,byte ptr low_rgt+1 ; last text line
- mov dgwindow[bx+2],ax ; fill remaining space with next wind
-
- push bx ; setup new margins, keep window ptr
- mov dghscrdis,0 ; horz scroll disable is disabled
- mov cx,slen ; max screen length
- mov al,mar_left
- xor bx,bx
- dgsetw6:mov linescroll[bx],al ; horiz scroll left margin to edge
- inc bx
- loop dgsetw6
- pop bx ; recover current line count in bx
-
- mov al,emubuf+4 ; get compressed/normal for this wind
- mov dh,byte ptr dgwindow[bx+1]; set cursor to bottom row of window
- or al,al ; to regular width?
- jnz dgsetw7 ; nz = no, to compressed
- call dgnarrow ; to normal width
- jmp short dgsetw8
- dgsetw7:call dgwide ; compress things
-
- dgsetw8:mov bx,dgwindcnt ; get window count
- or bx,bx ; any windows (0 = no)
- jz dgsetw9
- dec bx ; count from 0
- shl bx,1 ; count words
- mov al,byte ptr low_rgt+1 ; last text line on screen (typ 23)
- cmp byte ptr dgwindow[bx+1],al ; DG limit of 24 lines?
- jb dgsetw1 ; b = not reached yet, keep going
-
- dgsetw9:call dgshome ; do necessary DG Screen Home
- ret
- dgsetw endp
-
- dgwwa proc near ; Control-P col row
- mov ttstate,offset dgwwa1 ; DG Write window address (win rel)
- ret ; get raw binary col
- dgwwa1: mov emubuf,al ; save col
- mov ttstate,offset dgwwa2 ; get raw binary row
- ret
- dgwwa2: mov ttstate,offset atnrm ; reset state
- cmp al,127 ; 127 means use current row
- je dgwwa3 ; e = yes
- add al,mar_top ; relative to window top
- mov dh,al ; set cursor row
- dgwwa3: xor al,al ; get a zero
- xchg al,emubuf ; get raw column, clear temp word
- cmp al,127 ; 127 means use current column
- je dgwwa4 ; e = yes
- add al,mar_left ; add left margin
- mov dl,al ; new cursor position
- dgwwa4: cmp dh,mar_bot ; below bottom of window?
- jbe dgwwa5 ; be = no, in bounds
- mov dh,mar_bot ; peg at bottom
- dgwwa5: cmp dl,mar_right ; beyond right margin?
- jbe dgwwa6 ; be = no, in bounds
- mov dl,mar_right ; peg at right
- dgwwa6: jmp atsetcur ; set cursor within window
- dgwwa endp
-
- dgwsa proc near ; RS F P <nn><nn> Write screen address
- mov bx,offset dgwsa1 ; get <nn> col
- jmp get2n
- dgwsa1: mov ax,dgnum ; absolute column
- mov ah,mar_right ; right most virtual column
- cmp al,-1 ; means same screen column?
- je dgwsa2a ; e = yes
- cmp al,ah ; beyond right screen limit?
- jbe dgwsa2 ; be = no
- mov al,ah ; peg at the right
- dgwsa2: mov byte ptr cursor,al ; column of cursor
- dgwsa2a:mov bx,offset dgwsa3 ; get <nn> row
- jmp get2n
- dgwsa3: mov ax,dgnum ; get absolute row
- mov ah,byte ptr low_rgt+1 ; last text row
- cmp al,-1 ; means same screen row?
- je dgwsa5 ; e = yes
- cmp al,ah ; below text screen?
- jbe dgwsa4 ; be = no
- mov al,ah ; peg at the bottom
- dgwsa4: mov byte ptr cursor+1,al ; new row
- dgwsa5: mov dx,cursor
- call dggetmar ; get margins for this dx
- call getatch ; check for protected field
- test cl,att_protect ; protected?
- jz dgwsa6 ; z = no
- jmp dgcuf ; do DG cursor right
- dgwsa6: jmp atsetcur ; set cursor physical position
- dgwsa endp
-
- dgshome proc near ; RS F G DG Screen Home
- xor dh,dh ; absolute screen top
- call dggetmar ; get margins for this dx
- mov dl,mar_left ; go to left margin
- jmp atsetcur ; set the cursor
- dgshome endp
-
- dgsetmar proc near ; RS F X <nn> <nn> Set margins
- call dggetmar ; get margins for this window row
- mov bx,offset dgsetm1 ; get <nn> left margin
- jmp get2n
- dgsetm1:mov al,mar_left ; current left margin
- mov emubuf,al
- mov ax,dgnum ; get left margin info
- cmp al,-1 ; use current margin?
- je dgsetm2 ; e = yes
- mov emubuf,al ; set left margin
- dgsetm2:mov bx,offset dgsetm3 ; get right margin
- jmp get2n
- dgsetm3:mov ax,dgnum ; get right margin info
- cmp al,-1 ; use current margin?
- jne dgsetm4 ; ne = no
- mov al,vswidth-1 ; use full screen
- dgsetm4:cmp al,vswidth-1 ; check sanity
- ja dgsetmx ; a = too large a right margin
- or al,al ; how about zero too?
- jz dgsetmx ; z = bad value
- cmp al,mar_left ; getting things on the wrong side?
- ja dgsetm5 ; a = no
- mov al,mar_left
- inc al ; one column wide screen
- dgsetm5:mov mar_right,al ; set right margin
- cmp mar_left,vswidth-1 ; this side too
- jae dgsetmx ; ae = too large
- mov al,emubuf ; new left
- mov mar_left,al ; new left
- mov byte ptr cursor,al ; set cursor to left margin
- mov dx,cursor
- mov emubuf,al ; preset args for dgschw1
- mov al,mar_right
- mov emubuf+1,al
- jmp dgschw1 ; try to show both margins, set cursor
-
- dgsetmx:jmp dggetmar ; fail back to current margins
- dgsetmar endp
-
- dgsetamar proc near ; DG RS F Y <nn><nn><nn>
- cmp savdgmar,0 ; have we saved l/r margins?
- jne dgsetam0 ; ne = yes, don't save current
- mov ah,mar_right ; save originals
- mov al,mar_left
- mov savdgmar,ax ; saved
- dgsetam0:mov bx,offset dgsetam1 ; Set Alternate Margins
- jmp get2n ; get cursor row
- dgsetam1:mov ax,dgnum ; cursor row wrt top margin
- mov bl,dh ; row of cursor
- cmp al,-1 ; use current row?
- je dgsetam2 ; e = yes
- mov bl,mar_top ; get row at top of this window
- add bl,al ; new cursor row is mar_top + new
- dgsetam2:cmp bl,mar_bot ; below window?
- jbe dgsetam3 ; be = no
- mov bl,mar_bot ; clamp to window bottom
- dgsetam3:mov byte ptr param,bl ; save cursor row
- mov bx,offset dgsetam4 ; get <nn> col of new left margin
- jmp get2n
- dgsetam4:mov ax,dgnum
- mov bl,byte ptr savdgmar ; get permanent left margin
- cmp al,-1 ; use current left margin?
- je dgsetam5 ; e = yes
- add bl,al ; new left, wrt old left
- dgsetam5:mov param+2,bx ; save left margin
- mov bx,offset dgsetam6 ; get <nn> right margin
- jmp get2n
- dgsetam6:mov ax,dgnum
- mov bl,byte ptr savdgmar+1 ; current right margin
- cmp al,-1 ; use current right margin?
- je dgsetam7 ; e = yes
- mov bl,al
- add bl,byte ptr param+2 ; relative to new left margin
- cmp bl,byte ptr savdgmar+1 ; exceeds old right_margin?
- jbe dgsetam7 ; be = no
- mov bl,byte ptr savdgmar+1 ; yes, use old right_margin
- dgsetam7:cmp bl,vswidth-1 ; too far right?
- ja dgsetam9 ; a = yes, abandon the command
- mov mar_right,bl ; alt right margin
- mov al,byte ptr param+2 ; get alt left margin
- mov mar_left,al
- mov dl,al ; cursor to left margin
- mov dh,byte ptr param ; get row for cursor
- mov dghscrdis,1 ; horz scroll disabled (if 1)
- call atsetcur ; set cursor
- dgsetam9:ret
- dgsetamar endp
-
- dgrnmar proc near ; RS F Z DG Restore normal margins
- cmp savdgmar,0 ; anything saved?
- jz dgrnma1 ; z = no, do nothing
- xor ax,ax ; get a null
- xchg ax,savdgmar ; recover saved margins, clear saved
- mov mar_left,al
- mov mar_right,ah
- dgrnma1:ret
- dgrnmar endp
-
- ; Worker. Given cursor in dx, set mar_top, mar_bot based on finding the
- ; DG window for that cursor row.
- dggetmar proc near
- mov cx,dgwindcnt ; number of windows
- xor bx,bx
- jcxz dggetma2 ; z = none
- inc cx ; let implied last window be seen
- dggetma1:cmp dh,byte ptr dgwindow[bx+1] ; look at window bottom edge
- jbe dggetma3 ; be = cursor is in this window
- add bx,2 ; skip two margin bytes
- loop dggetma1 ; next window
- dggetma2:ret
-
- dggetma3:mov ax,dgwindow[bx] ; DG Window structure
- mov mar_top,al
- mov mar_bot,ah
- ret
- dggetmar endp
-
- ; Worker. Given cursor in dx, and al=mar_top, ah=mar_bot
- ; store these margins in the window structure for that row, based on
- ; finding the DG window for that cursor row.
- dgstoremar proc near
- push cx
- mov cx,dgwindcnt ; number of windows
- xor bx,bx
- jcxz dgstore2 ; z = none
- dgstore1:cmp dh,byte ptr dgwindow[bx+1] ; look at window bottom edge
- jbe dgstore2 ; be = cursor is in this window
- add bx,2 ; skip two margin bytes
- loop dgstore1 ; next window
- xor bx,bx ; fail, use first window slot
- dgstore2:pop cx
- mov dgwindow[bx],ax
- ret
- dgstoremar endp
-
- dgsmid proc near ; RS F { <nn><n> DG Set Model ID
- mov bx,offset dgsmid1 ; setup for <nn>
- jmp get2n
- dgsmid1:mov ax,dgnum ; get new model id
- mov byte ptr dgaltid,al ; save
- mov bx,dgsmid2 ; get graphics possible (1) bit
- jmp get1n
- dgsmid2:mov ax,dgnum
- mov byte ptr dgaltid+1,al
- ret
- dgsmid endp
-
- dgscrup proc near ; DG RS H
- mov scroll,1
- call atscru ; scroll up one line
- ret
- dgscrup endp
-
- dgscrdn proc near ; DG RS I
- mov scroll,1
- call atscrd ; scroll down one line
- ret
- dgscrdn endp
-
- dgcuu proc near ; Control-W DG cursor up
- mov cursor,dx ; remember for worker
- dgcuu1: cmp dh,mar_top ; above the top margin?
- ja dgcuu2 ; a = not on top margin
- mov dh,mar_bot ; roll to bottom margin
- inc dh
- dgcuu2: dec dh ; go up one row
- call dgcurpchk ; do proteced mode check
- jc dgcub1 ; c = protected, do cursor back
- jmp atsetcur ; set the cursor
- dgcuu endp
-
- dgcud proc near ; Control-Z DG cursor down
- mov cursor,dx ; remember for worker
- dgcud1: cmp dh,mar_bot ; below the bottom text line?
- jb dgcud2 ; b = no
- mov dh,mar_top ; roll to top margin
- dec dh
- dgcud2: inc dh ; go down one row
- call dgcurpchk ; check for protected cell
- jc dgcuf1 ; c = on protected cell, go forward
- jmp dgsetcur ; set cursor
- dgcud endp
-
- dgcuf proc near ; Control-X DG cursor forward
- mov cursor,dx ; remember where we started
- cmp dl,mar_right ; test for about to wrap
- jb dgcuf1 ; b = not wrapping
- test anspflg,vtautop ; printing desired?
- jz dgcuf1 ; e = no
- push dx ; save cursor value
- call pntlin ; print line current line
- mov al,LF ; terminate in LF
- call fpntchr
- call fpntflsh ; flush printer buffer
- mov atwrap,0
- pop dx
-
- dgcuf1: cmp dl,mar_right ; to right of right margin?
- jb dgcuf5 ; b = not on right margin
- mov dl,mar_left ; go to left margin
- inc dh ; and down one
- cmp dh,mar_bot ; below bottom line now?
- jbe dgcuf6 ; be = no
- mov dh,mar_bot ; stay on bottom line
- cmp dgroll,0 ; is roll mode disabled?
- jne dgcuf3 ; ne = no, do the scroll
- mov dh,mar_top ; yes, wrap to top
- jmp short dgcuf6
- dgcuf3: mov scroll,1
- call atsetcur ; set cursor before the scroll
- call atscru ; scroll up one line
- ret
- dgcuf5: inc dl ; go right one column
- dgcuf6: call dgcurpchk ; check protection
- jc dgcuf1 ; c = stepped on protected cell
- jmp atsetcur ; set cursor
- dgcuf endp
-
- dgcub proc near ; Control-Y DG cursor left
- mov cursor,dx ; remember for worker
- dgcub1: cmp dl,mar_left ; to left of left margin?
- ja dgcub2 ; a = no
- mov dl,mar_right ; go to right margin
- jmp dgcuu1 ; and do a cursor up
- dgcub2: dec dl ; go left one column
- call dgcurpchk ; check protection
- jc dgcub1 ; c = stepped on protected cell
- jmp atsetcur ; set real cursor and exit
- dgcub endp
-
- dgcurpchk proc near
- cmp protectena,0 ; protected mode enabled?
- je dgcurpc1 ; e = no
- call getatch ; read char under new cursor position
- test cl,att_protect ; protected?
- jz dgcurpc1 ; z = no, accept this position
- cmp dx,cursor ; is this where we started?
- je dgcurpc1 ; e = yes
- stc ; say stepping on protected char cell
- ret
- dgcurpc1:clc ; say no other action needed
- ret
- dgcurpchk endp
-
- ; Worker for cursor cmds. Skips protected fields, but remembers if we have
- ; come full circle and then does a cursor right from there. Enter with
- ; pre-motion cursor in "cursor", new desired position in dx.
- dgsetcur proc near
- call dgcurpchk ; call protected cell checker
- jnc dgsetcu1 ; nc = ok, accept this position
- jmp dgcuf1 ; do cursor forward
- dgsetcu1:mov bl,dh ; get row
- xor bh,bh
- cmp dl,linescroll[bx] ; to left of visible screen?
- jae dgsetcu2 ; ae = no
- mov emubuf,dl ; set desired left margin
- mov cl,mar_right
- mov emubuf+2,cl ; set desired right margin
- mov cursor,dx ; preset for dgschw1
- jmp dgschw1 ; do Show Window to track cursor
-
- dgsetcu2:jmp atsetcur ; set real cursor and exit
- dgsetcur endp
-
- dglf proc near ; Control-J DG New Line
- test anspflg,vtautop ; printing desired?
- jz dglf1 ; e = no
- push dx ; save cursor
- call pntlin ; print line
- mov al,LF ; terminate in LF
- call fpntchr
- call fpntflsh ; flush printer buffer
- mov atwrap,0
- pop dx
- dglf1: mov dl,mar_left ; to left margin
- cmp dh,mar_bot ; on bottom margin?
- jb dglf3 ; b = no
- cmp dgroll,0 ; is roll disabled
- je dglf2 ; e = yes, do home
- call dgsetcur ; set cursor, does show columns too
- mov scroll,1
- jmp atscru ; do a scroll up by one line
-
- dglf2: mov dh,mar_top ; do window Home
- jmp short dglf4
- dglf3: inc dh ; down one row
- dglf4: jmp dgsetcur ; set cursor wrt protected mode
- dglf endp
-
- dgcr proc near ; DG Control-M
- mov dl,mar_left ; go to left margin, same row
- jmp dgsetcur ; set cursor, with protected mode
- dgcr endp
-
- dgrmid proc near ; RS C DG Read Model ID
- mov al,dgescape ; resp RS o # <mm> <x> <y>
- call prtbout
- mov al,'o'
- call prtbout
- mov al,'#'
- call prtbout
- mov al,'6' ; 6 is DG D413/D463
- test flags.vtflg,ttd470 ; D470?
- jz dgrmid6 ; z = no
- mov al,44 ; 44 is DG D470
- dgrmid6:cmp byte ptr dgaltid,0 ; alternate ID given?
- je dgrmid1 ; e = no
- mov al,byte ptr dgaltid ; use alternate
- dgrmid1:call prtbout
- xor al,al ; <x> byte, clear it
- test flags.remflg,d8bit ; using 8 bits?
- jz dgrmid2 ; z = no
- or al,10h ; say 8-bit mode
- dgrmid2:push ax
- mov ah,ioctl ; get printer status, via DOS
- mov al,7 ; status for output
- push bx
- mov bx,4 ; std handle for system printer
- int dos
- pop bx
- jnc dgrmid3 ; nc = call succeeded
- mov al,0ffh
- dgrmid3:cmp al,0ffh ; code for Ready
- pop ax
- jne dgrmid4 ; ne = not ready
- or al,8 ; say printer present
- dgrmid4:or al,40h
- call prtbout ; send composite byte
- mov bl,vtemu.vtchset ; get Kermit NRC code (0-13)
- xor bh,bh
- mov al,nrcdgkbd[bx] ; <y>, get DG keyboard code from table
- or al,50h ; 01+kbd installed (no graphics)
- or al,20h ; say have graphics
- cmp byte ptr dgaltid,0 ; alternate id given?
- je dgrmid5 ; e = no
- cmp byte ptr dgaltid+1,0 ; host wants to say no graphics?
- jne dgrmid5 ; ne = no, let things stand
- and al,not 20h ; remove graphics bit
- dgrmid5:call prtbout
- ret
- dgrmid endp
- ; D470 command, absent from D463's
- dgscmap proc near ; RS F c <n><n><n><n> DG set color map
- mov bx,offset dgscmap1 ; get language ident
- jmp get3n ; get three of the <n>'s
- dgscmap1:mov bx,offset dgscmap2 ; get the fourth
- jmp get1n
- dgscmap2:ret
- dgscmap endp
-
- dgshcol proc near ; RS F _ <nn><nn> DG Show Columns
- mov bx,offset dgshco1 ; get left col to show
- jmp get2n
- dgshco1:mov ax,dgnum ; left column to show, is dominant
- mov cx,vswidth ; max columns in vscreen
- dec cx ; max column ident
- sub cl,byte ptr low_rgt ; visible display width - 1
- sbb ch,0 ; max left column showable
- cmp ax,cx ; want further right than this?
- jbe dgshco2 ; be = no
- mov ax,cx ; limit to max
- dgshco2:mov emubuf,al ; save max left col to show
- mov bx,offset dgshco3 ; get right col to show
- jmp get2n
- dgshco3:mov ax,dgnum ; right col
- mov emubuf+1,al
- cmp dghscrdis,0 ; is horizontal scrolling disabled?
- je dgschw1 ; e = no
- ret ; disabled, ignore this command
-
- ; worker. emubuf=wanted visible left, emubuf+1=wanted visible right margin
- dgschw1:mov bl,mar_top ; get window top
- xor bh,bh
- mov cl,mar_bot
- sub cl,bl
- inc cl
- xor ch,ch ; lines in window
- mov al,emubuf+1 ; desired right margin
- sub al,emubuf ; minus desired left
- cmp al,byte ptr low_rgt ; more than a screen's width?
- jbe dgschw2 ; be = no
- mov al,emubuf ; desired left
- add al,byte ptr low_rgt ; plus screen width
- mov emubuf+1,al ; chop desired rm to give one screen
-
- dgschw2:mov al,linescroll[bx] ; get scroll now in effect
- cmp emubuf,al ; is left margin to left of screen?
- jb dgshw4 ; b = yes, put it on screen
- je dgshw8 ; e = there now, do nothing
- mov ah,emubuf+1 ; right margin to use
- add al,byte ptr low_rgt ; visible right edge
- cmp al,ah ; visible vs wanted right edge
- jae dgshw8 ; ae = rm visible now, do nothing
- sub ah,al ; distance right margin is invisible
- xchg ah,al
- add al,linescroll[bx] ; new shift plus current shift
- jmp short dgshw5
-
- dgshw4: mov al,emubuf ; new scroll
- dgshw5: mov linescroll[bx],al ; horiz scroll for this line (window)
- inc bx
- loop dgshw5 ; do all lines in this window
- mov dx,cursor
- cmp dl,al ; is cursor off to the left?
- jae dgshw6 ; ae = no
- mov dl,al ; offset cursor too
- dgshw6: add al,byte ptr low_rgt ; visible right edge
- cmp dl,al ; cursor is on screen?
- jbe dgshw7 ; be = yes
- mov dl,al ; move cursor to right edge
- dgshw7: mov cursor,dx
- mov dl,mar_top ; region affected
- mov dh,mar_bot
- call touchup ; repaint based on new linescroll
- dgshw8: mov dx,cursor ; update visible cursor
- jmp atsetcur ; set cursor, updates screen
- dgshcol endp
-
- dgrnmod proc near ; RS F w DG Read New Model ID
- mov al,dgescape ; resp RS o w <c><s><r><n><res>
- call prtbout
- mov al,'o'
- call prtbout
- mov al,'w'
- call prtbout
- ; mov al,'3' ; <c> D413 level graphics terminal
- mov al,'8' ; <c> D470/D463 graphics terminal
- call prtbout
- mov al,'0' ; <s> pair, 01 is D470/D463
- call prtbout
- mov al,'1'
- call prtbout
- mov al,'0' ; <r> rev level as <nn>
- call prtbout ; report 00
- mov al,'0'
- call prtbout
- mov cx,4
- ;; mov si,offset d413model ; 8 char name, all printables
- mov si,offset d463model ; graphics term name, 8 printables
- test flags.vtflg,ttd470 ; D470?
- jz dgrnmo1 ; z = no
- mov si,offset d470model
- dgrnmo1:lodsb
- push cx
- call prtbout
- pop cx
- loop dgrnmo1
- mov cx,4+4 ; <reserved> four spaces
- dgrnmo2:mov al,' '
- push cx
- call prtbout
- pop cx
- loop dgrnmo2
- ret
- dgrnmod endp
-
- dgunix proc near ; RS P @ <n> DG Unix mode
- mov ttstate,offset dgunix1 ; setup to ignore @
- ret
- dgunix1:mov bx,offset atnrm ; consume the <n>
- jmp get1n
- dgunix endp
-
- dgsct proc near ; RS F Q <n> DG Set Cursor Type
- mov bx,offset dgsct1
- jmp get1n ; get the <n> arg
- dgsct1: mov ax,dgnum ; get cursor type
- or al,al ; case 0, invisible/off?
- jnz dgsct2 ; nz = no
- call csrtype ; set text cursor bits, keep kind
- or atctype,4 ; remember, is off
- jmp short dgsct5
-
- dgsct2: cmp al,2 ; standard 1,2? (underline, block)
- jbe dgsct4 ; be = yes
- sub al,5
- neg al ; 5 - AL
- js dgsct6 ; s = out of range, ignore
- jnz dgsct4 ; nz = cases 3 and 4 (block, uline)
- mov al,atctype ; case 5, use saved cursor type
- and al,not 4 ; remove invisible bit
- dgsct4: mov atctype,al ; save text cursor type here
- push ax
- or vtemu.vtflgop,vscursor ; set to underlined
- test al,2 ; setting to block?
- jz dgsct4a ; z = no, underline
- and vtemu.vtflgop,not vscursor ; say block in status word
- dgsct4a:call csrtype ; set the cursor bits
- pop ax
- dgsct5: test tekflg,tek_active+tek_sg ; special graphics mode active?
- jz dgsct6 ; z = no
- mov dx,cursor
- call teksetcursor ; set new cursor
- dgsct6: ret
- dgsct endp
-
- dgchatr proc near ; RS F N <nnn><n><n> DG change attrib
- mov bx,offset dgchat1 ; get <nnn> qty chars to change
- jmp get3n
- dgchat1:mov ax,dgnum ; qty chars to change
- mov word ptr emubuf,ax ; save
- mov bx,offset dgchat2 ; get <n> set list
- jmp get1n
- dgchat2:mov ax,dgnum ; bitfield for characteristics
- mov emubuf+2,al ; save set list
- mov bx,offset dgchat3 ; get final <n> reset list
- jmp get1n
- dgchat3:mov bl,byte ptr dgnum ; get reset list to BL
- mov emubuf+3,bl ; save reset list
- mov bh,emubuf+2 ; set list
- and bh,bl ; get toggle bits
- mov emubuf+4,bh ; save toggle list here
- not bh ; clear out bits processed here
- and emubuf+2,bh ; update set list
- and emubuf+3,bh ; update reset list
- mov cursor,dx ; save cursor location
-
- mov cx,word ptr emubuf ; qty of bytes to change, max
- or cx,cx ; some count?
- jnz dgchag4 ; nz = something to do
- ret
- dgchag4:mov al,extattr ; preserve settable attributes
- mov ah,scbattr
- push ax
- dgchag4a:push cx ; save loop counter
- call getatch ; get video in ah, extended att in cl
- mov extattr,cl ; place extended where procs can see
- mov emubuf+5,al ; save char
- call dgchag10 ; process this char
- mov al,emubuf+5 ; restore char
- call qsetatch ; quietly update the char
- pop cx
- inc dl ; next column
- cmp dl,mar_right ; at the right margin?
- jbe dgchag5 ; be = no, not yet
- mov dl,mar_left ; wrap to left and next line
- inc dh ; next line down
- cmp dh,mar_bot ; below the window bottom?
- ja dgchag6 ; a = yes, all done
- dgchag5:loop dgchag4a ; do more chars
- dgchag6:pop ax
- mov extattr,al ; restore setables
- mov scbattr,ah
- mov dl,byte ptr cursor+1 ; dl = starting row, dh = ending row
- mov dh,mar_bot
- call touchup ; repaint part of screen
- mov dx,cursor ; reset cursor location
- ret
-
- ; worker for dgchag ; do toggle mode
- dgchag10:mov bh,emubuf+4 ; toggle list
- or bh,bh ; any work?
- jz dgchag20 ; z = no
- test bh,1 ; blink?
- jz dgchag11 ; z = no
- xor ah,att_blink ; xor blink
- dgchag11:test bh,2 ; underscore?
- jz dgchag13 ; z = no
- test cl,att_uline ; is it set now?
- jz dgchag12 ; z = no
- call clrunder ; reset it
- jmp short dgchag13
- dgchag12:call setunder ; set it
- dgchag13:test bh,4 ; reverse video
- jz dgchag15 ; z = no
- test cl,att_rev ; reversed now?
- jz dgchag14 ; z = no
- call clrrev ; unreverse it
- jmp short dgchag15
- dgchag14:call setrev ; reverse it
- dgchag15:test bh,8 ; Dim
- jz dgchag20
- xor ah,att_bold
- ; do set list from emubuf+2
- dgchag20:mov bh,emubuf+2 ; get set list
- or bh,bh ; any work?
- jz dgchag30 ; z = no
- test bh,1 ; blink?
- jz dgchag21 ; z = no
- call setblink ; set blink
- dgchag21:test bh,2 ; underscore?
- jz dgchag22 ; z = no
- call setunder ; set underline
- dgchag22:test bh,4 ; reverse video?
- jz dgchag23 ; z = no
- call setrev ; set reverse video
- dgchag23:test bh,8 ; dim?
- jz dgchag30 ; z = no
- call clrbold ; set Dim
- ; do reset list from emubuf+3
- dgchag30:mov bh,emubuf+3 ; get reset list
- or bh,bh ; any work?
- jz dgchag34 ; z = no
- test bh,1 ; blink?
- jz dgchag31 ; z = no
- call clrblink ; clear blink
- dgchag31:test bh,2 ; underscore?
- jz dgchag32 ; z = no
- call clrunder ; clear underscore
- dgchag32:test bh,4 ; reverse video?
- jz dgchag33 ; z = no
- call clrrev
- dgchag33:test bh,8 ; Dim?
- jz dgchag34 ; z = no
- call setbold ; reset dim
- dgchag34:ret ; end of callable worker
- dgchatr endp
-
- dgsclk proc near ; RS r <n> <pos> <time> DG Set Clock
- mov bx,offset dgsclk1 ; set up to get <n><0000>
- jmp get3n
- dgsclk1:mov bx,offset dgsclk2 ; setup to get HH
- jmp get1n
- dgsclk2:mov ttstate,offset dgsclk3 ; setup to get ":"
- ret
- dgsclk3:mov bx,offset atnrm ; absorb final MM
- jmp get1n
- dgsclk endp
-
- dgrss proc near ; RS F t DG Report Screen Size
- mov al,dgescape ; resp RS o < <5 more items>
- call prtbout
- mov al,'o'
- call prtbout
- mov al,'<'
- call prtbout
- mov al,byte ptr low_rgt+1 ; number of screen rows -1
- inc al
- call out2n ; first item
- mov al,207 ; number of screen cols (DG hard #)
- call out2n ; second item
- mov al,mar_bot
- sub al,mar_top
- inc al ; third item, num rows in window
- call out2n
- mov al,mar_right
- sub al,mar_left
- inc al ; fourth item, num cols in window
- call out2n
- mov al,01110000b ; fifth item, status
- call prtbout
- ret
- dgrss endp
-
- dgrhso proc near ; RS F O DG Read Horz Scroll Offset
- mov al,dgescape ; resp RS o : <nn>
- call prtbout
- mov al,'o'
- call prtbout
- mov al,':'
- call prtbout
- mov bl,dh ; get current row
- xor bh,bh
- mov al,linescroll[bx] ; get scroll value
- call out2na
- ret
- dgrhso endp
-
- dgrwa proc near ; Control-E DG Read Window Address
- mov al,1fh ; Response string Control-_ col row
- call prtbout
- mov al,dl ; col, raw binary
- call prtbout
- mov al,dh ; row, raw binary
- call prtbout
- ret
- dgrwa endp
-
- dgrsa proc near ; RS F b DG Read Screen Address
- mov al,dgescape ; resp RS o 8 <nn> <nn>
- call prtbout
- mov al,'o'
- call prtbout
- mov al,'8'
- call prtbout
- mov al,byte ptr cursor ; column
- call out2na
- mov al,byte ptr cursor+1 ; row
- call out2na
- ret
- dgrsa endp
-
- dgrwc proc near ; RS F v <r1> <c1> <r2> <c2>
- mov emubufc,0 ; counter. DG Read Window Contents
- dgrwc1: mov bx,offset dgrwc2
- jmp get2n ; read <nn>
- dgrwc2: mov bx,emubufc ; get counter
- inc emubufc
- mov ax,dgnum ; r1, c1, r2, or c2
- mov emubuf[bx],al ; save here
- cmp bx,3 ; done all four?
- jb dgrwc1 ; b = no, get more
- mov dh,emubuf ; starting row
- cmp dh,emubuf+2 ; versus ending row
- ja dgrwc8 ; a = fail if wrong order
- dgrwc3: mov dl,emubuf+3 ; ending column
- mov cl,dl
- sub cl,emubuf+1 ; minus starting column
- jl dgrwc8 ; fail if wrong order
- inc cl ; number of cells to examine
- xor ch,ch
-
- dgrwc4: push cx
- push dx
- call direction
- call getatch ; read char into AL at cursor dx
- pop dx
- pop cx
- cmp al,' ' ; space?
- jne dgrwc5 ; found non-space
- dec dl
- loop dgrwc4
- dgrwc5: jcxz dgrwc7 ; z = only spaces on the line
- mov dl,emubuf+1 ; staring column
- dgrwc6: push cx
- push dx
- call direction
- call getatch ; get char and attribute
- call prtbout ; send char in al
- pop dx
- pop cx
- inc dl ; across the row
- loop dgrwc6 ; do all interesting cols
- dgrwc7: push dx
- mov al,CR ; send line terminators
- call prtbout
- mov al,LF
- call prtbout
- pop dx
- inc dh ; next row down
- cmp dh,emubuf+2 ; beyond last row?
- jbe dgrwc3 ; be = no
- mov dx,cursor
- mov emubufc,0 ; clear counter
- dgrwc8: ret
- dgrwc endp
- ; Data General D463/D470 graphics commands
-
- dggline proc near ; RS L and RS G 8 DG line drawing
- call dgsettek ; setup special graphics mode
- dggline1:mov bx,offset dggline2 ; get <NNN> x coord
- jmp get3loc
- dggline2:jc dggline9 ; c = read null terminator
- mov ax,dgnum ; start x coord
- mov param+0,ax ; save here
- mov param+4,ax ; and here
- mov bx,offset dggline3 ; get <NNN> y coord
- jmp get3loc
- dggline3:jc dggline9
- mov ax,dgnum
- mov param+2,ax ; start y
- mov param+6,ax ; and here
- dggline4:mov bx,offset dggline5 ; get <NNN> end x coord
- jmp get3loc
- dggline5:jc dggline8 ; c = ending on single coord, do a dot
- mov ax,dgnum
- mov param+4,ax ; end x
- mov bx,offset dggline6 ; get <NNN> end y coord
- jmp get3loc
- dggline6:jc dggline9 ; c = null char
- mov ax,dgnum ; end y
- mov param+6,ax
- call dggline8 ; plot line
- jmp short dggline4 ; continue gathering coord pairs
-
- dggline8:
- push word ptr mar_top ; mar_top in low byte
- push dglinepat ; line pattern
- push param+6 ; end y
- push param+4 ; end x
- push param+2 ; start y
- push param+0 ; start x
- call dgline ; do the line
- add sp,12 ; clear the argument stack
- mov ax,param+4 ; old end is new beginning
- mov param,ax
- mov ax,param+6
- mov param+2,ax
- dggline9:ret
- dggline endp
-
- dggarc proc near ; RS G 0 DG arc drawing
- mov bx,offset dggarc1 ; get <NNN> x coord
- jmp get3loc
- dggarc1:jc dggarc9 ; unexpected terminator
- mov ax,dgnum ; x coord
- mov param,ax ; save here
- mov bx,offset dggarc2 ; get <NNN> y coord
- jmp get3loc
- dggarc2:jc dggarc9
- mov ax,dgnum
- mov param+2,ax
- mov bx,offset dggarc3 ; get <NNN> radius
- jmp get3loc
- dggarc3:jc dggarc9
- mov ax,dgnum
- mov param+4,ax
- mov bx,offset dggarc4 ; get <NNN> start angle
- jmp get3loc
- dggarc4:jc dggarc9
- mov ax,dgnum
- mov param+6,ax
- mov bx,offset dggarc5 ; get <NNN> end angle
- jmp get3loc
- dggarc5:call dgsettek ; setup graphics mode
- mov al,mar_bot ; bottom margin in PC text lines
- xor ah,ah
- push ax
- mov al,mar_top ; top margin in PC text lines
- push ax
- push dgnum ; end angle
- push param+6 ; start angle
- push param+4 ; radius
- push param+2 ; start y
- push param+0 ; start x
- call dgarc ; draw the arc in msgibm
- add sp,14 ; clean stack
- dggarc9:ret
- dggarc endp
-
- dggbar proc near ; RS G 1 DG bar drawing
- call dgsettek ; setup special graphics mode
- mov bx,offset dggbar1 ; get <NNN> x coord, lower left
- jmp get3loc
- dggbar1:jc dggbar9 ; c = unexpected terminator
- mov ax,dgnum ; x coord
- mov param,ax ; save here
- mov bx,offset dggbar2 ; get <NNN> y coord
- jmp get3loc
- dggbar2:jc dggbar9
- mov ax,dgnum
- mov param+2,ax
- mov bx,offset dggbar3 ; get <NNN> width
- jmp get3loc
- dggbar3:jc dggbar9
- mov ax,dgnum
- mov param+4,ax
- mov bx,offset dggbar4 ; get <NNN> height
- jmp get3loc
- dggbar4:jc dggbar9
- mov ax,dgnum
- mov param+6,ax
- mov bx,offset dggbar5 ; get <n> foreground/background
- jmp get1n
- dggbar5:jc dggbar9
- xor ah,ah
- mov al,mar_bot
- push ax
- mov al,mar_top
- push ax
- push dgnum ; fore(1) or background (0) color
- push param+6 ; height
- push param+4 ; width
- push param+2 ; start y lower left corner
- push param+0 ; start x
- call dgbar ; msgibm bar drawer
- add sp,14 ; clean stack
- dggbar9:ret
- dggbar endp
-
- dggpoly proc near ; RS G : DG polygon fill drawing
- mov word ptr rdbuf,0 ; count argument pairs
- dggpol1:mov bx,offset dggpol2 ; get <NNN> x coord
- jmp get3loc
- dggpol2:jc dggpol4 ; c = got null terminator
- mov ax,dgnum ; x coord
- mov param,ax ; save here
- mov bx,offset dggpol3 ; get <NNN> y coord
- jmp get3loc
- dggpol3:jc dggpol4
- mov bx,word ptr rdbuf ; vertex index
- shl bx,1 ; count words
- shl bx,1 ; count pairs
- mov cx,param ; x coord
- mov ax,dgnum ; y coord
- mov word ptr rdbuf+2[bx],cx ; stuff x
- mov word ptr rdbuf+2[bx+2],ax ; stuff y
- inc word ptr rdbuf ; another vertex in list
- jmp short dggpol1 ; get another vertex
- dggpol4:cmp word ptr rdbuf,3 ; minimum viable point count
- jb dggpol6 ; b = insufficient qty
- mov bx,word ptr rdbuf ; vertex index
- shl bx,1 ; count words
- shl bx,1 ; count pairs
- mov al,mar_top
- xor ah,ah
- mov word ptr rdbuf+2[bx],ax ; top margin, PC text lines
- mov al,mar_bot
- mov word ptr rdbuf+2[bx+2],ax ; bottom margin, PC text lines
- call dgsettek ; setup special graphics mode
- mov al,curattr ; save current coloring
- push ax
- test flags.vtflg,ttd463 ; D463?
- jz dgpoly5 ; z = no
- and al,0f0h ; remove foreground
- or al,dg463fore ; OR in D463 foreground color
- mov curattr,al ; set drawing coloring
- dgpoly5:call dgpoly ; call worker in msgibm
- pop ax
- mov curattr,al ; restore coloring
- dggpol6:ret
- dggpoly endp
-
- dggsetp proc near ; RS G p 1 DG Set Pattern
- mov ttstate,offset dggset1 ; setup to read the 1
- ret
- dggset1:cmp al,'1' ; correct?
- je dggset2 ; e = yes
- dggsetx:jmp atnorm ; fail and reset state
- dggset2:mov ttstate,offset dggset3 ; setup to read <offset>
- mov dglinepat,0 ; init line pattern to all zeros
- call dgsettek ; setup special graphics mode
- ret
- dggset3:sub al,'@' ; remove ASCII bias
- jc dggset9 ; c = failure
- and al,1fh ; keep lower five bits
- xor ah,ah
- mov param,ax ; save initial bit position
- mov cl,al
- rcl dglinepat,cl ; rotate initial pattern
- mov ttstate,offset dggset4 ; setup to read <n> 0/1 bit
- ret
- dggset4:or al,al ; null terminator?
- jz dggset6 ; z = yes
- and al,0fh ; keep lower four bits of <n>
- cmp al,1 ; legal values are 0, 1, and other
- jbe dggset5 ; be = 0 or 1
- xor al,al ; above 1 is made to be zero
- dggset5:rcr al,1
- rcr dglinepat,1 ; put into line pattern high bit
- inc param ; count bit added to pattern
- ret ; continue in state dggset4
-
- dggset6:mov cx,16 ; bits in pattern
- sub cx,param ; get pattern bit count
- jle dggset9 ; le = rotated enough
- mov ax,dglinepat ; pattern
- mov bx,ax ; a copy
- mov cx,param ; pattern bit count
- mov dx,16 ; overall bits
- dggset6a:sub dx,cx ; minus original pattern
- jg dggset7 ; g = still have room to copy
- je dggset8 ; e = all done
- neg dx
- mov cx,dx ; else tag end
- dggset7:ror ax,cl ; rotate pattern to starting position
- or ax,bx ; move in a copy
- jmp short dggset6a
-
- dggset8:mov dglinepat,ax ; store line pattern
- dggset9:mov ttstate,offset atnrm
- ret
- dggsetp endp
-
- dggrcl proc near ; RS G ? | DG Read Cursor Location
- mov ttstate,offset dggrcl1
- ret
- dggrcl1:mov ttstate,atnrm ; reset state
- cmp al,'|' ; correct terminator?
- jne dggrcl3 ; ne = no
- dggrcl2:call dgcrossrpt ; generate report in msgibm
- dggrcl3:ret
- dggrcl endp
-
- dggcon proc near ; RS G B DG Cursor on
- call dgsettek ; setup special graphics mode
- call dgcrosson ; turn on crosshair
- ret
- dggcon endp
-
- dggcoff proc near ; RS G C DG Cursor off
- call dgcrossoff ; turn off crosshair
- ret
- dggcoff endp
-
- dggcloc proc near ; RS G > | <NNN> <NNN> DG Cursor loc
- mov ttstate,offset dggclo1 ; get vertical bar
- ret
- dggclo1:mov ttstate,offset atnrm ; reset state
- cmp al,'|' ; correct character?
- je dggclo2 ; e = yes
- ret
- dggclo2:mov bx,offset dggclo3 ; get <nnn> x ordinate
- jmp get3loc ; as 15 bit location argument
- dggclo3:mov ax,dgnum
- mov param,ax ; got x ordinate
- mov bx,offset dggclo4 ; get <nnn> y ordinate
- jmp get3loc ; as 15 bit location argument
- dggclo4:mov bx,dgnum ; setup registers for call
- mov ax,param
- call dgsetcrloc ; setup crosshair location
- ret
- dggcloc endp
-
- dggctrk proc near ; RS G H <n> DG Cursor track
- mov bx,offset dggctr1
- jmp get1n
- dggctr1:and al,2+4 ; pick out our trackables
- and dgcross,not (2+4) ; preserve on/of bit (1)
- or dgcross,al ; track keypad (2) and/or mouse (4)
- ret
- dggctrk endp
-
- dggcatt proc near ; RS G @ DG graphics cursor attribute
- mov al,dgescape
- call prtbout
- mov al,'o'
- call prtbout
- mov al,','
- call prtbout
- mov al,'0' ; say crosshair is off
- test dgcross,1 ; is it on?
- jz dggcatt1 ; z = no
- inc al ; say '1' for on
- dggcatt1:call prtbout ; output <v1>
- mov al,'0' ; <v2> is always 0 for not blinking
- call prtbout
- mov al,'1' ; <v3> is 1 for long crosshair, D463
- test flags.vtflg,ttd470 ; D470?
- jz dggcatt2 ; z = no
- dec al ; <v3> is 0 for short crosshair, D470
- dggcatt2:call prtbout
- mov al,dgcross ; get tracked devices
- and al,2+4 ; pick out just devices
- add al,'0' ; bias
- call prtbout ; output <v4>
- mov al,CR ; terminal character
- call prtbout
- ret
- dggcatt endp
-
- dggcrst proc near ; RS G A DG Cursor reset
- call dgcrossoff ; turn off crosshair
- mov dgcross,0 ; and no kind of tracking
- ret
- dggcrst endp
-
- ; End of Data General specific routines
-
-
- ; Display "LEDs" routine. yflags from MSYIBM is needed to know if the mode
- ; line is enabled. Display current state of "LEDs" on line 25.
- ansdsl proc near ; display "LEDs"
- test yflags,modoff ; mode line off?
- jnz ansdsl2 ; nz = yes, just return
- cmp flags.modflg,1 ; mode line on and owned by us?
- jne ansdsl2 ; ne = no, leave it intact
- mov cx,10 ; length of the array
- call getled ; set si to string, c set if no leds
- push es
- mov di,ds
- mov es,di
- mov di,led_col+offset modbuf ; mode line buffer, our position
- cld
- rep movsb
- pop es
- ansdsl2:ret
- ansdsl endp
-
- ; Return pointer to "led" display in si, set carry if terminal type does
- ; not have leds 1..4.
- getled proc near
- mov ax,flags.vtflg ; terminal type
- mov si,offset v320leds ; VT320 ident
- cmp ax,ttvt320 ; VT320?
- je getled2 ; e = yes
- mov si,offset v220leds ; VT220 ident
- cmp ax,ttvt220 ; VT220?
- je getled2 ; e = yes
- mov si,offset v102leds ; VT102 ident
- cmp ax,ttvt102 ; VT102 mode?
- je getled2 ; e = yes
- mov si,offset v100leds
- cmp ax,ttvt100 ; VT100?
- je getled2 ; e = yes
- mov si,offset honeyleds
- cmp ax,tthoney ; Honeywell?
- je getled2 ; e = yes
- mov si,offset v52leds ; VT52 ident
- cmp ax,ttvt52 ; VT52?
- je getled1 ; e = yes, no leds
- mov si,offset pt20leds
- cmp ax,ttpt200 ; Prime PT200?
- je getled2 ; e = yes
- mov si,offset d463leds
- cmp ax,ttd463 ; DG D463?
- je getled1 ; e = yes, but no led dots
- mov si,offset d470leds
- cmp ax,ttd470 ; DG D470?
- je getled1 ; e = yes, but no led dots
- mov si,offset h19leds ; Heath-19 ident
- getled1:stc ; c = set, does not have leds 1..4
- ret
- getled2:clc ; c = clear, has leds 1..4
- ret
- getled endp
-
- ; This routine is called to adjust the cursor for the "indexing" like commands
- ; (e.g., index, reverse index, newline, etc.). It contrains the cursor, and
- ; indicates if scrolling is necessary, and if so, in which direction.
- ;
- ; Call: cursor = "old" cursor position
- ; dx = "new" cursor position
- ;
- ; Return: ax = pointer to scrolling routine to call (or to a ret)
- ; bx = "old" cursor position
- ; dx = "new" cursor position adjusted for screen limits or
- ; scrolling region, depending on whether the original
- ; cursor position was inside or outside the scrolling region.
- ;
- ; On the VT100, a scroll does not occur unless the original cursor position
- ; was on the top or bottom margin. This routine assumes that when decom is
- ; set the cursor position is set to the new origin, and that no other routine
- ; allows the cursor to be positioned outside the scrolling region as long
- ; as decom is set (which is the way a real VT100 works). Note that for the
- ; normal case (no limited scrolling region defined) the margins are the same
- ; as the screen limits and scrolling occurs (as on a "normal" terminal) when
- ; an attempt is made to index off the screen. Preserves cx.
-
- atccic proc near
- push cx
- mov cl,byte ptr low_rgt ; get right margin
- mov bl,dh ; get row
- xor bh,bh
- cmp bl,crt_lins ; below screen?
- jae atcci0 ; ae = yes, use single width line
- cmp linetype[bx],0 ; single width chars?
- je atcci0 ; e = yes, single width
- shr cl,1 ; halve margin for double wides
- atcci0: mov ax,offset atign ; assume no scrolling necessary
- mov bx,cursor ; get old cursor
- test flags.vtflg,ttd463+ttd470 ; DG terminal?
- jz atcci0a ; z = no
- mov cl,mar_right
- cmp dl,mar_left ; left of left margin?
- jae atcci1 ; ae = no
- mov dl,mar_right ; fold to right
- dec dh ; and go up
- jmp short atcci1
- atcci0a:cmp dl,250 ; left of left margin? (wide screen)
- jb atcci1 ; b = no, go check right
- xor dl,dl ; set to left margin
- atcci1: cmp dl,cl ; left of right margin
- jbe atcci2 ; be = yes, go check top
- mov dl,cl ; set to right margin
- test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jz atcci2 ; z = no
- mov dl,mar_left ; to left margin
- inc dh ; and down one
- atcci2: pop cx
- cmp bh,mar_top ; was old pos above scroll top margin?
- jb atcci7 ; b = yes
- cmp dh,mar_top ; want to go above top margin?
- jge atcci5 ; ge = no
- test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jz atcci3 ; z = no
- mov dh,mar_bot ; roll over to bottom margin
- ret
- atcci3: mov scroll,1
- mov ax,offset atscrd ; indicate scroll down required
- mov dh,mar_top ; set to top margin
- ret
-
- atcci5: cmp bh,mar_bot ; old position below bottom margin?
- ja atcci7 ; a = yes
- cmp dh,mar_bot ; want to go below?
- jbe atcci6 ; be = no, nothing to worry about
- mov scroll,1 ; 1 line
- mov ax,offset atscru ; indicate scroll up required
- mov dh,mar_bot ; set to bottom margin
- atcci6: ret
- atcci7: jmp short atccpc ; old pos was outside scrolling region
- atccic endp
-
- ; This routine is called to check the cursor position after any kind of cursor
- ; positioning command. Note that cursor positioning does NOT cause scrolling
- ; on a VT100 (hence the need for a routine separate from this for "indexing".
- ; Call: dx = "new" cursor position (modified cursor)
- ; Return: dx = "new" cursor position adjusted for screen limits (if
- ; decom is reset), or scrolling region (if decom is set).
- ; Preserves ax, bx, and cx.
-
- atccpc proc near
- push bx ; save bx and cx
- push cx
- mov cx,low_rgt ; margins, cl = right margin
- mov bl,dh ; get row
- xor bh,bh
- cmp linetype [bx],0 ; single width line?
- je atccp0 ; e = yes, single width
- shr cl,1 ; halve right margin for double wides
- atccp0: test flags.vtflg,ttd463+ttd470 ; DG terminal?
- jz atccp0a ; z = no
- mov cl,mar_right
- cmp dl,mar_left ; left of margin?
- jae atccp1 ; ae = no
- mov dl,mar_right ; go to right margin
- dec dh ; do a cursor up
- jmp short atccp1 ; do a cursor up
-
- atccp0a:cmp dl,250 ; to left of left margin?(wide screen)
- jb atccp1 ; b = no, go check right
- xor dl,dl ; set to left margin
- atccp1: cmp dl,cl ; to right of right margin?
- jbe atccp2 ; be = yes, go check top
- mov dl,cl ; set to right margin
-
- test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jz atccp2 ; z = no
- mov dl,mar_left ; to left margin
- jmp atlf ; do a LF operation now
-
- atccp2: pop cx
- pop bx
- test vtemu.vtflgop,decom ; Origin mode set?
- jnz atccp5 ; nz = yes, stay in scrolling region
- or dh,dh ; above top of screen?
- jae atccp3 ; ae = no, check bottom
- xor dh,dh ; stop here
- atccp3: cmp dh,byte ptr low_rgt+1 ; below bottom of screen?
- jbe atccp4 ; be = no, stay in margins
- mov dh,byte ptr low_rgt+1 ; stop at end of text screen
- cmp flags.vtflg,ttheath ; Heath-19 mode?
- jne atccp4 ; ne = no
- test h19stat,h19l25 ; 25th line enabled?
- jnz atccp4 ; nz = yes
- inc dh ; allow 25th line
- atccp4: ret
-
- atccp5: cmp dh,mar_top ; above top of scrolling region?
- jae atccp6 ; ae = no, check bottom
- mov dh,mar_top ; yes, stop there
- test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jz atccp6 ; z = no
- mov dh,mar_bot ; roll to bottom
- ret
- atccp6: cmp dh,mar_bot ; below bottom perhaps?
- jbe atccp4 ; be = no, return
- mov dh,mar_bot ; yes, stop at the bottom margin
- test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jz atccp7 ; z = no
- mov dh,mar_top ; roll to top
- atccp7: ret
- atccpc endp
-
-
- ; Routine to set cursor type (off, block, underline).
- ; 4 = do not show, but keep block/underline attributes.
- ; 2 = block, 1 = underline
- atsctyp:cmp flags.vtflg,ttheath ; Heath-19?
- jne atsct1 ; ne = no
- mov al,h19ctyp ; get cursor kind and on/off bit
- test al,4 ; is cursor to be off?
- jz atsct4 ; z = no, al has kind
- xor al,al ; turn off cursor
- jmp short atsct4 ; do it
- atsct1: test atctype,4 ; VTxxx cursor type, off?
- jnz atsct3 ; z = no
- atsct2: mov al,1 ; assume underline
- test vtemu.vtflgop,vscursor ; block?
- jnz atsct3 ; nz = no, underline
- inc al
- atsct3: mov atctype,al ; save VTxxx cursor type here
- atsct4: call csrtype ; set the cursor type
- ret
-
- atdeb proc near ; Debug, display all chars in tty style
- test yflags,capt ; capturing output?
- jz atdeb3 ; z = no, forget this part
- call fcptchr ; give it captured character
- atdeb3: mov bl,curattr ; save attribute
- push bx
- push word ptr mar_top ; save limited scrolling region
- push ax ; save character for a second
- mov ah,curattr ; get attribute
- call clrblink ; clear blink attribute
- call clrunder ; clear underline attribute
- mov extattr,0 ; extended attribute
- mov curattr,ah ; store
- or vtemu.vtflgop,decawm ; set autowrap temporarily
- mov mar_top,0 ; set scrolling region to entire page
- mov al,byte ptr low_rgt+1
- mov mar_bot,al
- pop ax ; restore character
- test al,80h ; high bit set?
- jz atdeb0 ; z = not set
- push ax ; save the character for a second
- mov al,7eh ; output a tilde
- call atnrm2
- pop ax ; restore character
- and al,7fh ; and remove high bit
- atdeb0: cmp al,del ; DEL?
- je atdeb1 ; e = yes, output "^?"
- cmp al,20h ; control character?
- jnb atdeb2 ; nb = no, just output char in al
- atdeb1: push ax ; save the character for a second
- mov al,5eh ; output a caret
- call atnrm2
- pop ax ; restore character
- add al,40h ; make ^letter (or ^? for DEL)
- and al,7fh ; clear bit 7 (for DEL)
- atdeb2: call atnrm2 ; output translated character
- pop word ptr mar_top ; restore scrolling region,
- pop bx ; flags, and cursor attribute
- mov curattr,bl
- ret
- atdeb endp
- code1 ends
- end
-